Skip to main content

proka_kernel/process/
task.rs

1extern crate alloc;
2use alloc::vec::Vec;
3use lazy_static::lazy_static;
4use spin::Mutex;
5
6lazy_static! {
7    pub static ref TASK_MANAGER: Mutex<TaskManager> = Mutex::new(TaskManager::new());
8}
9
10/// Defintion of task state
11pub enum TaskState {
12    /// The init state, which means the task is ready to
13    /// run by CPU.
14    Ready,
15
16    /// Sign the process is currently running.
17    Running,
18
19    /// If the process has completed running, sign it as
20    /// terminated.
21    Terminated,
22}
23
24/// The object of a task.
25#[allow(unused)]
26pub struct Task {
27    /// The ID of this task.
28    ///
29    /// This uses type "u16", which means the task limit is
30    /// 65535. (id range is 0~65535)
31    id: u16,
32
33    /// The state of the task.
34    state: TaskState,
35
36    /// The priority of the kernel (1-8)
37    priority: u8,
38}
39
40impl Task {
41    /// Create a new task object.
42    pub fn new(id: u16, priority: u8) -> Self {
43        Self {
44            id,
45            state: TaskState::Ready,
46            priority,
47        }
48    }
49
50    /// Change the status of a task.
51    pub fn update_stat(&mut self, new_state: TaskState) {
52        self.state = new_state
53    }
54}
55
56/// The task manager which contains lots of tasks.
57pub struct TaskManager {
58    /// The field which contains all tasks.
59    tasks: Vec<Task>,
60
61    /// The task ID which has been allocated.
62    allocated_tid: Vec<u16>,
63
64    /// The next task id
65    next_tid: u16,
66}
67
68impl TaskManager {
69    pub const fn new() -> Self {
70        Self {
71            tasks: Vec::new(),
72            allocated_tid: Vec::new(),
73            next_tid: 0,
74        }
75    }
76
77    pub fn create_task(&mut self, priority: u8) {
78        // Allocate a task id
79        let mut task_id = self.next_tid;
80
81        // Check: is current ID has been allocated
82        if self.allocated_tid.contains(&task_id) {
83            task_id += 1;
84        }
85
86        // Push the task to the tasks container
87        self.tasks.push(Task::new(task_id, priority));
88
89        // Set the current id is allocated.
90        self.allocated_tid.push(task_id);
91
92        // Set up new ID
93        self.next_tid = self.next_tid.wrapping_add(1);
94    }
95
96    pub fn delete_task(&mut self, task_id: u16) -> Result<(), &'static str> {
97        // Check is task ID allocated.
98        if !self.allocated_tid.contains(&task_id) {
99            return Err("The task ID is unable to discovor.");
100        }
101
102        // Find the task to remove from [`tasks`].
103        Ok(())
104    }
105}
106
107impl Default for TaskManager {
108    fn default() -> Self {
109        Self::new()
110    }
111}