os/kernel/task/
mod.rs

1//! 任务模块
2//!
3//! 包含任务的创建、调度、终止等功能
4//! 并由任务管理器维护所有任务的信息
5use core::sync::atomic::Ordering;
6
7mod cap;
8mod cred;
9mod futex;
10mod ktask;
11mod process;
12mod task_manager;
13mod task_state;
14mod task_struct;
15mod tid_allocator;
16mod work_queue;
17
18pub use cap::*;
19pub use cred::*;
20pub use futex::*;
21pub use ktask::*;
22pub use process::*;
23pub use task_manager::{TASK_MANAGER, TaskManagerTrait};
24pub use task_state::TaskState;
25pub use task_struct::FsStruct;
26pub use task_struct::SharedTask;
27pub use task_struct::Task as TaskStruct;
28pub use work_queue::*;
29
30use alloc::sync::Arc;
31
32use crate::mm::memory_space::MemorySpace;
33use crate::sync::SpinLock;
34use crate::uapi::signal::NUM_SIGCHLD;
35use crate::{
36    arch::trap::{TrapFrame, restore},
37    kernel::{cpu::current_cpu, schedule},
38    vfs::{FDTable, File, FsError},
39};
40
41/// 新创建的线程发生第一次调度时会从 forkret 开始执行
42/// 该函数负责恢复任务的陷阱帧,从而进入任务的实际执行上下文
43pub(crate) fn forkret() {
44    let fp: *mut TrapFrame;
45    {
46        let cpu = current_cpu().lock();
47        let task = cpu.current_task.as_ref().unwrap();
48        fp = task.lock().trap_frame_ptr.load(Ordering::SeqCst);
49    }
50    // SAFETY: fp 指向的内存已经被分配且由当前任务拥有
51    unsafe { restore(&*fp) };
52}
53
54/// 在任务结束时调用的函数
55/// 任务正常地执行完毕后通过创建时预先设置的寄存器跳转到该函数
56/// 该函数不会返回,负责清理任务资源并切换到下一个任务
57/// 参数:
58/// * `code`: 任务的退出码
59pub(crate) fn terminate_task(code: usize) -> ! {
60    let task = {
61        let cpu = current_cpu().lock();
62        cpu.current_task.as_ref().unwrap().clone()
63    };
64
65    {
66        let mut t = task.lock();
67        // 不必将task移出cpu,在schedule时会处理
68        t.state = TaskState::Zombie;
69        t.exit_code = Some(code as i32);
70    }
71    drop(task);
72    schedule();
73    unreachable!("terminate_task: should not return after scheduled out terminated task");
74}
75
76/// 获取当前task
77/// # 返回值:当前任务的SharedTask
78pub fn current_task() -> SharedTask {
79    current_cpu()
80        .lock()
81        .current_task
82        .as_ref()
83        .expect("current_task: CPU has no current task")
84        .clone()
85}
86
87/// 获取当前任务的内存空间
88/// # 返回值:当前任务的内存空间
89pub fn current_memory_space() -> Arc<SpinLock<MemorySpace>> {
90    current_cpu()
91        .lock()
92        .current_memory_space
93        .as_ref()
94        .expect("current_memory_space: current task has no memory space")
95        .clone()
96}
97
98/// 通知父任务子任务状态变化
99/// # 参数:
100/// * `task`: 子任务
101pub fn notify_parent(task: SharedTask) {
102    let ppid = {
103        let t = task.lock();
104        t.ppid
105    };
106
107    let t = TASK_MANAGER.lock();
108    if let Some(p) = t.get_task(ppid) {
109        // 1. 发送信号 (Wake up signal path)
110        // 注意:send_signal 会短暂获取 p 锁
111        t.send_signal(p.clone(), NUM_SIGCHLD);
112
113        // 2. 唤醒等待队列 (WaitQueue path)
114        // 必须显式唤醒,因为 sys_wait4 等待在 wait_child 上
115        // 这里的关键是不能持有 p 锁调用 wake_up,否则死锁 (Recursive Parent Lock)
116        let wait_child = p.lock().wait_child.clone();
117        // 释放 p 锁 (t lock 也在 get_task 后如果 drop? 不,t held here)
118        // t is TASK_MANAGER lock. p.lock() is Parent lock.
119        // We hold TM lock. We hold Parent lock (briefly).
120        // Then we hold WaitQueue lock.
121        // wait_child.lock().wake_up_one() -> Locks Scheduler -> Locks Parent.
122        // If we hold TM lock: TM -> WaitQueue -> Parent.
123        // Is Parent -> TM possible? No.
124
125        // So this is safe.
126        wait_child.lock().wake_up_one();
127    } else {
128        // Parent not found (e.g. init process exiting), ignore
129        let pid = task.lock().pid;
130        crate::pr_warn!(
131            "notify_parent: parent task {} not found for child {}",
132            ppid,
133            pid
134        );
135    }
136}
137
138/// 获取当前任务的文件描述符表
139pub fn current_fd_table() -> Arc<FDTable> {
140    current_task().lock().fd_table.clone()
141}
142
143/// 从当前任务的 FD 表中获取文件
144pub fn get_file(fd: usize) -> Result<Arc<dyn File>, FsError> {
145    current_fd_table().get(fd)
146}