mirror of
https://github.com/phil-opp/blog_os.git
synced 2025-12-16 14:27:49 +00:00
Add a yield_now function and use it in idle thread
This commit is contained in:
@@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user