os/kernel/scheduler/
task_queue.rs1use alloc::{sync::Arc, vec::Vec};
5
6use crate::kernel::task::SharedTask;
7
8#[derive(Debug)]
11pub struct TaskQueue {
12 queue: Vec<SharedTask>,
13}
14
15impl TaskQueue {
16 pub fn new() -> Self {
18 TaskQueue { queue: Vec::new() }
19 }
20
21 pub fn add_task(&mut self, task: SharedTask) {
23 self.queue.push(task);
24 }
25
26 pub fn remove_task(&mut self, task: &SharedTask) {
28 self.queue.retain(|t| !Arc::ptr_eq(t, task));
29 }
30
31 pub fn pop_task(&mut self) -> Option<SharedTask> {
33 if !self.queue.is_empty() {
34 Some(self.queue.remove(0))
35 } else {
36 None
37 }
38 }
39
40 pub fn contains(&self, task: &SharedTask) -> bool {
42 for t in &self.queue {
43 if Arc::ptr_eq(t, task) {
44 return true;
45 }
46 }
47 false
48 }
49
50 pub fn is_empty(&self) -> bool {
52 self.queue.is_empty()
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use crate::{kassert, kernel::task::TaskStruct, test_case};
60 use alloc::sync::Arc;
61
62 fn mk_task(tid: u32) -> SharedTask {
63 TaskStruct::new_dummy_task(tid).into_shared()
64 }
65
66 test_case!(test_task_queue_add_and_contains, {
68 let mut q = TaskQueue::new();
69 kassert!(q.is_empty());
70
71 let t1 = mk_task(1);
72 let t2 = mk_task(2);
73
74 q.add_task(t1.clone());
75 q.add_task(t2.clone());
76
77 kassert!(q.contains(&t1));
78 kassert!(q.contains(&t2));
79 kassert!(!q.is_empty());
80 });
81
82 test_case!(test_task_queue_pop_order_fifo, {
84 let mut q = TaskQueue::new();
85 let t1 = mk_task(10);
86 let t2 = mk_task(11);
87 q.add_task(t1.clone());
88 q.add_task(t2.clone());
89
90 let p1 = q.pop_task().expect("expected first task");
91 let p2 = q.pop_task().expect("expected second task");
92 kassert!(Arc::ptr_eq(&p1, &t1));
93 kassert!(Arc::ptr_eq(&p2, &t2));
94 kassert!(q.pop_task().is_none());
95 kassert!(q.is_empty());
96 });
97
98 test_case!(test_task_queue_remove_task, {
100 let mut q = TaskQueue::new();
101 let t1 = mk_task(20);
102 let t2 = mk_task(21);
103 let t3 = mk_task(22);
104 q.add_task(t1.clone());
105 q.add_task(t2.clone());
106 q.add_task(t3.clone());
107
108 q.remove_task(&t2);
109 kassert!(!q.contains(&t2));
110 kassert!(q.contains(&t1));
111 kassert!(q.contains(&t3));
112
113 let p1 = q.pop_task().unwrap();
115 let p2 = q.pop_task().unwrap();
116 kassert!(Arc::ptr_eq(&p1, &t1));
117 kassert!(Arc::ptr_eq(&p2, &t3));
118 kassert!(q.is_empty());
119 });
120
121 test_case!(test_task_queue_contains_arc_identity, {
123 let mut q = TaskQueue::new();
124 let t1 = mk_task(30);
125 let t1_clone = t1.clone();
126 let t1_other = mk_task(30); q.add_task(t1.clone());
129 kassert!(q.contains(&t1));
130 kassert!(q.contains(&t1_clone));
131 kassert!(!q.contains(&t1_other));
132 });
133
134 test_case!(test_task_queue_empty_state, {
136 let mut q = TaskQueue::new();
137 kassert!(q.is_empty());
138 let t = mk_task(40);
139 q.add_task(t.clone());
140 kassert!(!q.is_empty());
141 let _ = q.pop_task();
142 kassert!(q.is_empty());
143 });
144}