os/task/
task.rs

1use super::id::TaskUserRes;
2use super::{KernelStack, ProcessControlBlock, TaskContext, kstack_alloc};
3use crate::trap::TrapContext;
4use crate::{mm::PhysPageNum, sync::UPSafeCell};
5use alloc::sync::{Arc, Weak};
6use core::cell::RefMut;
7
8pub struct TaskControlBlock {
9    // immutable
10    pub process: Weak<ProcessControlBlock>,
11    pub kstack: KernelStack,
12    // mutable
13    inner: UPSafeCell<TaskControlBlockInner>,
14}
15
16impl TaskControlBlock {
17    pub fn inner_exclusive_access(&self) -> RefMut<'_, TaskControlBlockInner> {
18        self.inner.exclusive_access()
19    }
20
21    pub fn get_user_token(&self) -> usize {
22        let process = self.process.upgrade().unwrap();
23        let inner = process.inner_exclusive_access();
24        inner.memory_set.token()
25    }
26}
27
28pub struct TaskControlBlockInner {
29    pub res: Option<TaskUserRes>,
30    pub trap_cx_ppn: PhysPageNum,
31    pub task_cx: TaskContext,
32    pub task_status: TaskStatus,
33    pub exit_code: Option<i32>,
34}
35
36impl TaskControlBlockInner {
37    pub fn get_trap_cx(&self) -> &'static mut TrapContext {
38        self.trap_cx_ppn.get_mut()
39    }
40
41    #[allow(unused)]
42    fn get_status(&self) -> TaskStatus {
43        self.task_status
44    }
45}
46
47impl TaskControlBlock {
48    pub fn new(
49        process: Arc<ProcessControlBlock>,
50        ustack_base: usize,
51        alloc_user_res: bool,
52    ) -> Self {
53        let res = TaskUserRes::new(Arc::clone(&process), ustack_base, alloc_user_res);
54        let trap_cx_ppn = res.trap_cx_ppn();
55        let kstack = kstack_alloc();
56        let kstack_top = kstack.get_top();
57        Self {
58            process: Arc::downgrade(&process),
59            kstack,
60            inner: unsafe {
61                UPSafeCell::new(TaskControlBlockInner {
62                    res: Some(res),
63                    trap_cx_ppn,
64                    task_cx: TaskContext::goto_trap_return(kstack_top),
65                    task_status: TaskStatus::Ready,
66                    exit_code: None,
67                })
68            },
69        }
70    }
71}
72
73#[derive(Copy, Clone, PartialEq)]
74pub enum TaskStatus {
75    Ready,
76    Running,
77    Blocked,
78}