os/kernel/task/
task_manager.rs

1//! 任务管理器模块
2//!
3//! 该模块定义了任务管理器的接口和实现
4//! 任务管理器负责管理系统中的所有任务
5//! 包括任务的创建、销毁和查找等功能
6//! 内部维护一个任务映射表,使用任务 ID 作为键
7//! 并提供分配唯一任务 ID 的功能
8//! 注意:该模块的实例应当被包装在适当的同步原语中以确保线程安全
9use alloc::collections::btree_map::BTreeMap;
10use alloc::vec::Vec;
11
12use crate::kernel::task::SharedTask;
13use crate::kernel::task::tid_allocator::TidAllocator;
14use crate::kernel::{TaskState, exit_task_with_block, wake_up_with_block};
15use crate::sync::SpinLock;
16use crate::uapi::signal::SignalFlags;
17
18use lazy_static::lazy_static;
19
20lazy_static! {
21    pub static ref TASK_MANAGER: SpinLock<TaskManager> = SpinLock::new(TaskManager::new());
22}
23
24/// 任务管理器接口
25///
26/// 任务管理器负责所有与任务数据结构相关的修改。
27/// 具体来说,它负责以下几项工作:
28/// 1. 填写返回值(退出状态)。在 exit 流程中,任务管理器将进程的退出码写入其进程描述符中。
29/// 2. 数据结构维护: 维护进程描述符(task_struct)中的所有数据,如 PID、父子关系、权限、打开的文件列表等。
30/// 3. 任务生命周期管理: 负责任务的创建、销毁和查找等功能。
31/// 注意:任务运行状态的修改由调度器负责
32pub trait TaskManagerTrait {
33    /// 创建一个新的任务管理器实例
34    /// 返回值: TaskManager 结构体
35    /// 该实例初始化了任务 ID 分配器和任务映射表
36    fn new() -> Self;
37
38    /// 分配一个唯一的任务 ID
39    /// 返回值: 分配的任务 ID
40    fn allocate_tid(&mut self) -> u32;
41
42    /// 将一个任务添加到任务管理器中
43    /// 参数:
44    /// * `task`: 需要添加的任务,类型为 SharedTask
45    fn add_task(&mut self, task: SharedTask);
46
47    /// 将一个任务标记为退出
48    /// 参数:
49    /// * `tid`: 需要退出的任务 ID
50    fn exit_task(&mut self, task: SharedTask, code: i32);
51
52    /// 释放一个已退出的任务
53    /// 参数:
54    /// * `task`: 需要释放的任务,类型为 SharedTask
55    fn release_task(&mut self, task: SharedTask);
56
57    /// 根据任务 ID 获取对应的任务
58    /// 参数:
59    /// * `tid`: 需要获取的任务 ID
60    ///   返回值: 如果找到对应任务则返回 Some(SharedTask),否则返回 None
61    fn get_task(&self, tid: u32) -> Option<SharedTask>;
62
63    /// 根据条件获取符合条件的任务列表
64    /// 参数:
65    /// * `cond`: 用于筛选任务的条件函数,接受一个 SharedTask 参数并返回 bool
66    /// 返回值: 符合条件的任务列表
67    fn get_task_cond(&self, cond: impl Fn(&SharedTask) -> bool) -> Vec<SharedTask>;
68
69    /// 获取进程(线程组)内所有线程
70    /// 参数:
71    /// * `pid`: 进程 ID
72    /// 返回值: 该进程内所有线程的列表
73    fn get_process_threads(&self, process: SharedTask) -> Vec<SharedTask>;
74
75    /// 获取进程的所有子进程
76    /// 参数:
77    /// * `pid`: 进程 ID
78    /// 返回值: 该进程的所有子进程列表
79    fn get_process_children(&self, process: SharedTask) -> Vec<SharedTask>;
80
81    /// 发送信号给指定任务
82    /// 参数:
83    /// * `task`: 目标任务对应的 SharedTask
84    /// * `signal`: 需要发送的信号编号
85    /// 返回值: 如果任务存在且信号发送成功则返回 true,否则返回 false
86    fn send_signal(&self, task: SharedTask, signal: usize) -> bool;
87
88    /// 获取所有任务
89    /// 返回值: 所有任务的列表
90    fn get_all_tasks(&self) -> Vec<SharedTask>;
91
92    #[cfg(test)]
93    /// 获取当前任务数量(仅用于测试)
94    /// 返回值: 当前任务数量
95    fn task_count(&self) -> usize;
96}
97
98/// 任务管理器,负责管理所有任务的生命周期和调度
99/// 包括任务的创建、销毁和查找等功能
100/// 内部维护一个任务映射表,使用任务 ID 作为键
101/// 并提供分配唯一任务 ID 的功能
102/// 注意:该结构体的实例应当被包装在适当的同步原语中以确保线程安全
103pub struct TaskManager {
104    tid_allocator: TidAllocator,
105    tasks: BTreeMap<u32, SharedTask>,
106}
107
108impl TaskManagerTrait for TaskManager {
109    fn new() -> Self {
110        TaskManager {
111            tid_allocator: TidAllocator::new(),
112            tasks: BTreeMap::new(),
113        }
114    }
115
116    fn allocate_tid(&mut self) -> u32 {
117        self.tid_allocator.allocate()
118    }
119
120    fn add_task(&mut self, task: SharedTask) {
121        let tid = task.lock().tid;
122        self.tasks.insert(tid, task);
123    }
124
125    fn exit_task(&mut self, task: SharedTask, code: i32) {
126        {
127            let mut task = task.lock();
128            task.exit_code = Some(code as i32);
129        }
130        exit_task_with_block(task);
131    }
132
133    fn release_task(&mut self, task: SharedTask) {
134        self.tasks.remove(&task.lock().tid);
135    }
136
137    fn get_task(&self, tid: u32) -> Option<SharedTask> {
138        self.tasks.get(&tid).cloned()
139    }
140
141    fn get_task_cond(&self, cond: impl Fn(&SharedTask) -> bool) -> Vec<SharedTask> {
142        let mut v = Vec::new();
143        for task in self.tasks.values() {
144            if cond(task) {
145                v.push(task.clone());
146            }
147        }
148        v
149    }
150
151    fn get_process_threads(&self, process: SharedTask) -> Vec<SharedTask> {
152        let mut v = Vec::new();
153        let pid = process.lock().pid;
154        for task in self.tasks.values() {
155            if task.lock().pid == pid {
156                v.push(task.clone());
157            }
158        }
159        v
160    }
161
162    fn get_process_children(&self, process: SharedTask) -> Vec<SharedTask> {
163        process.lock().children.lock().clone()
164    }
165
166    fn send_signal(&self, task: SharedTask, signal: usize) -> bool {
167        if let Some(signal_flag) = SignalFlags::from_signal_num(signal) {
168            let mut t = task.lock();
169            t.pending.signals.insert(signal_flag);
170            if t.state == TaskState::Interruptible {
171                drop(t);
172                wake_up_with_block(task.clone());
173            }
174            true
175        } else {
176            false
177        }
178    }
179
180    fn get_all_tasks(&self) -> Vec<SharedTask> {
181        self.tasks.values().cloned().collect()
182    }
183
184    #[cfg(test)]
185    fn task_count(&self) -> usize {
186        self.tasks.len()
187    }
188}
189
190#[cfg(test)]
191mod tests {
192    use alloc::sync::Arc;
193
194    use super::*;
195    use crate::{
196        kassert,
197        kernel::{TaskState, task::TaskStruct},
198        sync::SpinLock,
199        test_case,
200    };
201
202    fn new_dummy_task(tid: u32) -> SharedTask {
203        let task = TaskStruct::new_dummy_task(tid);
204        Arc::new(SpinLock::new(task))
205    }
206
207    // 通过 TaskManager 分配 tid:应从 1 开始递增
208    test_case!(test_task_manager_allocate_sequence, {
209        let mut tm = TaskManager::new();
210        let t1 = tm.allocate_tid();
211        let t2 = tm.allocate_tid();
212        let t3 = tm.allocate_tid();
213        kassert!(t1 == 1);
214        kassert!(t2 == 2);
215        kassert!(t3 == 3);
216    });
217
218    // 对不存在的 tid 进行查询与退出
219    test_case!(test_task_manager_get_remove_nonexistent, {
220        let mut tm = TaskManager::new();
221        // 查询不存在的任务
222        kassert!(tm.get_task(42).is_none());
223
224        // 删除不存在的任务(应为 no-op)
225        tm.exit_task(new_dummy_task(42), 0);
226        kassert!(tm.get_task(42).is_none());
227    });
228
229    // 关于 add_task/get_task/exit_task 的正向测试
230    test_case!(test_task_manager_add_get_exit, {
231        let mut tm = TaskManager::new();
232        let tid = tm.allocate_tid();
233        let task = new_dummy_task(tid);
234        tm.add_task(task.clone());
235        kassert!(tm.get_task(tid).is_some());
236
237        const EXIT_CODE: i32 = 42;
238
239        // 任务管理器执行退出操作(设置返回值和通知调度器)
240        tm.exit_task(task, EXIT_CODE);
241
242        let exited_task = tm.get_task(tid).unwrap();
243        let g = exited_task.lock();
244
245        // 验证任务管理器设置了返回值 (新的责任)
246        kassert!(g.exit_code == Some(EXIT_CODE as i32));
247
248        // 验证调度器设置了状态 (调度器的责任)
249        kassert!(g.state == TaskState::Zombie);
250    });
251
252    // 释放已退出任务的测试
253    test_case!(test_task_manager_release_task, {
254        let mut tm = TaskManager::new();
255        let tid = tm.allocate_tid();
256        let task = new_dummy_task(tid);
257        tm.add_task(task.clone());
258
259        // 任务退出(此时状态为 Zombie,仍在 tasks 列表中)
260        tm.exit_task(task.clone(), 0);
261        kassert!(tm.task_count() == 1);
262
263        // 释放任务
264        tm.release_task(task);
265        kassert!(tm.task_count() == 0);
266        kassert!(tm.get_task(tid).is_none());
267    });
268}