1use super::{ProcessControlBlock, TaskControlBlock, TaskStatus};
2use crate::sync::UPIntrFreeCell;
3use alloc::collections::{BTreeMap, VecDeque};
4use alloc::sync::Arc;
5use lazy_static::*;
6
7pub struct TaskManager {
8 ready_queue: VecDeque<Arc<TaskControlBlock>>,
9}
10
11impl TaskManager {
13 pub fn new() -> Self {
14 Self {
15 ready_queue: VecDeque::new(),
16 }
17 }
18 pub fn add(&mut self, task: Arc<TaskControlBlock>) {
19 self.ready_queue.push_back(task);
20 }
21 pub fn fetch(&mut self) -> Option<Arc<TaskControlBlock>> {
22 self.ready_queue.pop_front()
23 }
24}
25
26lazy_static! {
27 pub static ref TASK_MANAGER: UPIntrFreeCell<TaskManager> =
28 unsafe { UPIntrFreeCell::new(TaskManager::new()) };
29 pub static ref PID2PCB: UPIntrFreeCell<BTreeMap<usize, Arc<ProcessControlBlock>>> =
30 unsafe { UPIntrFreeCell::new(BTreeMap::new()) };
31}
32
33pub fn add_task(task: Arc<TaskControlBlock>) {
34 TASK_MANAGER.exclusive_access().add(task);
35}
36
37pub fn wakeup_task(task: Arc<TaskControlBlock>) {
38 let mut task_inner = task.inner_exclusive_access();
39 task_inner.task_status = TaskStatus::Ready;
40 drop(task_inner);
41 add_task(task);
42}
43
44pub fn fetch_task() -> Option<Arc<TaskControlBlock>> {
45 TASK_MANAGER.exclusive_access().fetch()
46}
47
48pub fn pid2process(pid: usize) -> Option<Arc<ProcessControlBlock>> {
49 let map = PID2PCB.exclusive_access();
50 map.get(&pid).map(Arc::clone)
51}
52
53pub fn insert_into_pid2process(pid: usize, process: Arc<ProcessControlBlock>) {
54 PID2PCB.exclusive_access().insert(pid, process);
55}
56
57pub fn remove_from_pid2process(pid: usize) {
58 let mut map = PID2PCB.exclusive_access();
59 if map.remove(&pid).is_none() {
60 panic!("cannot find pid {} in pid2task!", pid);
61 }
62}