Add a yield_now function and use it in idle thread

This commit is contained in:
Philipp Oppermann
2020-01-28 12:28:50 +01:00
parent 22c6bd5aa7
commit b337f65abb
3 changed files with 19 additions and 12 deletions

View File

@@ -74,6 +74,7 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! {
fn idle_thread() -> ! { fn idle_thread() -> ! {
loop { loop {
x86_64::instructions::hlt(); x86_64::instructions::hlt();
multitasking::yield_now();
} }
} }

View File

@@ -9,6 +9,7 @@ static SCHEDULER: spin::Mutex<Option<Scheduler>> = spin::Mutex::new(None);
#[repr(u64)] #[repr(u64)]
pub enum SwitchReason { pub enum SwitchReason {
Paused, Paused,
Yield,
Blocked, Blocked,
Exit, Exit,
} }
@@ -29,19 +30,22 @@ pub fn invoke_scheduler() {
} }
pub fn exit_thread() -> ! { pub fn exit_thread() -> ! {
synchronous_context_switch(SwitchReason::Exit).expect("can't exit last thread");
unreachable!("finished thread continued");
}
pub fn yield_now() {
let _ = synchronous_context_switch(SwitchReason::Yield);
}
fn synchronous_context_switch(reason: SwitchReason) -> Result<(), ()> {
let next = with_scheduler(|s| s.schedule()); let next = with_scheduler(|s| s.schedule());
match next { match next {
Some((next_stack_pointer, prev_thread_id)) => { Some((next_stack_pointer, prev_thread_id)) => unsafe {
unsafe { context_switch::context_switch_to(next_stack_pointer, prev_thread_id, reason);
context_switch::context_switch_to( Ok(())
next_stack_pointer, },
prev_thread_id, None => Err(()),
SwitchReason::Exit,
)
}
unreachable!("finished thread continued")
}
None => panic!("can't exit last thread"),
} }
} }

View File

@@ -74,7 +74,9 @@ impl Scheduler {
return; // do nothing return; // do nothing
} }
match switch_reason { match switch_reason {
SwitchReason::Paused => self.paused_threads.push_back(paused_thread_id), SwitchReason::Paused | SwitchReason::Yield => {
self.paused_threads.push_back(paused_thread_id)
}
SwitchReason::Blocked => { SwitchReason::Blocked => {
self.blocked_threads.insert(paused_thread_id); self.blocked_threads.insert(paused_thread_id);
self.check_for_wakeup(paused_thread_id); self.check_for_wakeup(paused_thread_id);