os/kernel/scheduler/
wait_queue.rs1use crate::kernel::task::SharedTask;
5use crate::kernel::{TaskQueue, sleep_task_with_block, wake_up_with_block, yield_task};
6use crate::sync::RawSpinLock;
7use alloc::vec::Vec;
8
9#[derive(Debug)]
22pub struct WaitQueue {
23 tasks: TaskQueue,
24 lock: RawSpinLock,
25}
26
27impl WaitQueue {
28 pub fn new() -> Self {
30 WaitQueue {
31 tasks: TaskQueue::new(),
32 lock: RawSpinLock::new(),
33 }
34 }
35
36 pub fn sleep(&mut self, task: SharedTask) {
38 let _g = self.lock.lock();
39 self.tasks.add_task(task.clone());
40 sleep_task_with_block(task, true);
41 }
42
43 pub fn wake_up(&mut self, task: &SharedTask) {
45 let should_wake = {
46 let _g = self.lock.lock();
47 if self.tasks.contains(task) {
48 self.tasks.remove_task(task);
49 true
50 } else {
51 false
52 }
53 };
54 if should_wake {
55 wake_up_with_block(task.clone());
56 }
57 }
58
59 pub fn wake_up_one(&mut self) {
61 let maybe_task = {
62 let _g = self.lock.lock();
63 self.tasks.pop_task()
64 };
65 if let Some(t) = maybe_task {
66 wake_up_with_block(t);
67 }
68 }
69
70 pub fn wake_up_all(&mut self) {
72 let mut to_wake: Vec<SharedTask> = Vec::new();
73 {
74 let _g = self.lock.lock();
75 while let Some(t) = self.tasks.pop_task() {
76 to_wake.push(t);
77 }
78 }
79 for t in to_wake {
80 wake_up_with_block(t);
81 }
82 }
83
84 pub fn add_task(&mut self, task: SharedTask) {
86 let _g = self.lock.lock();
87 self.tasks.add_task(task);
88 }
89
90 pub fn remove_task(&mut self, task: &SharedTask) {
92 let _g = self.lock.lock();
93 self.tasks.remove_task(task);
94 }
95
96 pub fn contains(&self, task: &SharedTask) -> bool {
98 let _g = self.lock.lock();
99 self.tasks.contains(task)
100 }
101
102 pub fn is_empty(&self) -> bool {
104 let _g = self.lock.lock();
105 self.tasks.is_empty()
106 }
107
108 pub fn sleep_if<F>(&mut self, task: SharedTask, check_fn: F) -> bool
111 where
112 F: FnOnce() -> bool,
113 {
114 let _g = self.lock.lock();
115 if check_fn() {
116 return false; }
118 self.tasks.add_task(task.clone());
119 sleep_task_with_block(task, true);
120 true }
122}
123
124unsafe impl Send for WaitQueue {}
128unsafe impl Sync for WaitQueue {}