os/kernel/scheduler/
task_queue.rs

1//! 任务队列模块
2//!
3//! 定义了任务队列结构体及其相关操作
4use alloc::{sync::Arc, vec::Vec};
5
6use crate::kernel::task::SharedTask;
7
8/// 任务队列
9/// 用于存放任务
10#[derive(Debug)]
11pub struct TaskQueue {
12    queue: Vec<SharedTask>,
13}
14
15impl TaskQueue {
16    /// 创建一个新的队列
17    pub fn new() -> Self {
18        TaskQueue { queue: Vec::new() }
19    }
20
21    /// 向运行队列添加任务
22    pub fn add_task(&mut self, task: SharedTask) {
23        self.queue.push(task);
24    }
25
26    /// 从运行队列中移除任务
27    pub fn remove_task(&mut self, task: &SharedTask) {
28        self.queue.retain(|t| !Arc::ptr_eq(t, task));
29    }
30
31    /// 从运行队列中弹出一个任务
32    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    /// 检查任务是否在队列中
41    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    /// 检查队列是否为空
51    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    // 基础:新增后应存在于队列,队列非空
67    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    // FIFO 顺序:先入先出
83    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    // 移除:从中间删除应仅移除指定项
99    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        // 弹出剩下的两项,顺序应保持相对顺序(t1 -> t3)
114        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    // contains 语义:同一 Arc 克隆应视为相等;不同对象即便 tid 相同也不相等
122    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); // 不同实例(即便 tid 相同)
127
128        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    // 空队列状态切换
135    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}