use super::{ProcessControlBlock, TaskControlBlock, TaskStatus}; use crate::sync::UPIntrFreeCell; use alloc::collections::{BTreeMap, VecDeque}; use alloc::sync::Arc; use lazy_static::*; pub struct TaskManager { ready_queue: VecDeque>, } /// A simple FIFO scheduler. impl TaskManager { pub fn new() -> Self { Self { ready_queue: VecDeque::new(), } } pub fn add(&mut self, task: Arc) { self.ready_queue.push_back(task); } pub fn fetch(&mut self) -> Option> { self.ready_queue.pop_front() } } lazy_static! { pub static ref TASK_MANAGER: UPIntrFreeCell = unsafe { UPIntrFreeCell::new(TaskManager::new()) }; pub static ref PID2PCB: UPIntrFreeCell>> = unsafe { UPIntrFreeCell::new(BTreeMap::new()) }; } pub fn add_task(task: Arc) { TASK_MANAGER.exclusive_access().add(task); } pub fn wakeup_task(task: Arc) { let mut task_inner = task.inner_exclusive_access(); task_inner.task_status = TaskStatus::Ready; drop(task_inner); add_task(task); } pub fn fetch_task() -> Option> { TASK_MANAGER.exclusive_access().fetch() } pub fn pid2process(pid: usize) -> Option> { let map = PID2PCB.exclusive_access(); map.get(&pid).map(Arc::clone) } pub fn insert_into_pid2process(pid: usize, process: Arc) { PID2PCB.exclusive_access().insert(pid, process); } pub fn remove_from_pid2process(pid: usize) { let mut map = PID2PCB.exclusive_access(); if map.remove(&pid).is_none() { panic!("cannot find pid {} in pid2task!", pid); } }