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() -> ! {
loop {
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)]
pub enum SwitchReason {
Paused,
Yield,
Blocked,
Exit,
}
@@ -29,19 +30,22 @@ pub fn invoke_scheduler() {
}
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());
match next {
Some((next_stack_pointer, prev_thread_id)) => {
unsafe {
context_switch::context_switch_to(
next_stack_pointer,
prev_thread_id,
SwitchReason::Exit,
)
}
unreachable!("finished thread continued")
}
None => panic!("can't exit last thread"),
Some((next_stack_pointer, prev_thread_id)) => unsafe {
context_switch::context_switch_to(next_stack_pointer, prev_thread_id, reason);
Ok(())
},
None => Err(()),
}
}

View File

@@ -74,7 +74,9 @@ impl Scheduler {
return; // do nothing
}
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 => {
self.blocked_threads.insert(paused_thread_id);
self.check_for_wakeup(paused_thread_id);