use crate::process::Process;
use alloc::{collections::BTreeMap, vec::Vec};
use core::cell::UnsafeCell;
use tg_task_manage::{Manage, PManager, ProcId, Schedule};
pub struct Processor {
inner: UnsafeCell<PManager<Process, ProcManager>>,
}
unsafe impl Sync for Processor {}
impl Processor {
pub const fn new() -> Self {
Self {
inner: UnsafeCell::new(PManager::new()),
}
}
#[inline]
pub fn get_mut(&self) -> &mut PManager<Process, ProcManager> {
unsafe { &mut (*self.inner.get()) }
}
}
pub static PROCESSOR: Processor = Processor::new();
pub struct ProcManager {
tasks: BTreeMap<ProcId, Process>,
ready_queue: Vec<ProcId>,
}
impl ProcManager {
pub fn new() -> Self {
Self {
tasks: BTreeMap::new(),
ready_queue: Vec::new(),
}
}
}
impl Manage<Process, ProcId> for ProcManager {
#[inline]
fn insert(&mut self, id: ProcId, task: Process) {
self.tasks.insert(id, task);
}
#[inline]
fn get_mut(&mut self, id: ProcId) -> Option<&mut Process> {
self.tasks.get_mut(&id)
}
#[inline]
fn delete(&mut self, id: ProcId) {
self.tasks.remove(&id);
}
}
impl Schedule<ProcId> for ProcManager {
fn add(&mut self, id: ProcId) {
if !self.ready_queue.contains(&id) {
self.ready_queue.push(id);
}
}
fn fetch(&mut self) -> Option<ProcId> {
let mut best: Option<(usize, u128, ProcId)> = None;
for (idx, &id) in self.ready_queue.iter().enumerate() {
let Some(task) = self.tasks.get(&id) else {
continue;
};
match best {
Some((_, best_stride, best_id))
if task.stride > best_stride
|| (task.stride == best_stride && id > best_id) => {}
_ => best = Some((idx, task.stride, id)),
}
}
let (idx, _, id) = best?;
self.ready_queue.remove(idx);
if let Some(task) = self.tasks.get_mut(&id) {
task.advance_stride();
Some(id)
} else {
None
}
}
}