os/kernel/scheduler/
mod.rs1mod rr_scheduler;
5mod task_queue;
6mod wait_queue;
7
8use lazy_static::lazy_static;
9
10use crate::{
11 arch::kernel::{context::Context, switch},
12 kernel::{TaskStruct, current_task, scheduler::rr_scheduler::RRScheduler, task::SharedTask},
13 pr_debug,
14 sync::{SpinLock, SpinLockGuard},
15};
16
17pub use task_queue::TaskQueue;
18pub use wait_queue::WaitQueue;
19
20lazy_static! {
21 pub static ref SCHEDULER: SpinLock<RRScheduler> = SpinLock::new(RRScheduler::new());
22}
23
24pub(crate) struct SwitchPlan {
26 pub old: *mut Context,
27 pub new: *const Context,
28}
29
30pub trait Scheduler {
36 fn new() -> Self;
38 fn add_task(&mut self, task: SharedTask);
42 fn next_task(&mut self) -> Option<SwitchPlan>;
46 fn sleep_task(&mut self, task: SharedTask, receive_signal: bool);
53 fn wake_up(&mut self, task: SharedTask);
58 fn exit_task(&mut self, task: SharedTask);
63 fn sleep_task_with_guard(
72 &mut self,
73 task: &mut SpinLockGuard<'_, TaskStruct>,
74 stask: SharedTask,
75 receive_signal: bool,
76 );
77}
78
79pub fn schedule() {
81 let plan = {
82 let mut sched = SCHEDULER.lock();
83 sched.next_task()
85 };
86
87 if let Some(plan) = plan {
88 pr_debug!("Switched to task {}", current_task().lock().tid);
89 unsafe { switch(plan.old, plan.new) };
91 }
93}
94
95pub fn yield_task() {
99 schedule();
100}
101
102pub fn sleep_task_with_block(task: SharedTask, receive_signal: bool) {
109 SCHEDULER.lock().sleep_task(task, receive_signal);
110}
111
112pub fn wake_up_with_block(task: SharedTask) {
117 SCHEDULER.lock().wake_up(task);
118}
119
120pub fn exit_task_with_block(task: SharedTask) {
125 SCHEDULER.lock().exit_task(task);
126}
127
128pub fn sleep_task_with_guard_and_block(
137 task: &mut SpinLockGuard<'_, TaskStruct>,
138 stask: SharedTask,
139 receive_signal: bool,
140) {
141 SCHEDULER
142 .lock()
143 .sleep_task_with_guard(task, stask, receive_signal);
144}