use core::arch; // WasmContext use crate::{arch::sloop, interp::WasmContext}; use alloc::vec::Vec; use log::trace; pub type ProcId = u64; pub struct Scheduler { running: Vec, halted: Vec<(ContextWake, WasmContext)>, // time_halt: Vec<(ContextWake, WasmContext)>, next_proc_id: ProcId, } impl Scheduler { pub fn new() -> Scheduler { Self { running: Vec::new(), halted: Vec::new(), // time_halt: Vec::new(), next_proc_id: 0, } } pub fn run(&mut self) -> ! { loop { let proc = self.running.pop(); // self.time_halt.sort(); match proc { Some(proc) => { // trace!("SWAP WasmContext"); self.running.push(proc); } None => { panic!("nothing scheduled."); sloop(); } } } } fn sleep_inner(&self, id: ProcId) -> Result { let proc_len = self.running.len(); let mut proc_found = true; let mut sleep_index = 0; let mut i = 0; for wc in &self.running { if wc.proc_id == Some(id) { sleep_index = i; proc_found = true; break; } if i == proc_len { proc_found = false; trace!("no process with ID {} found", id); return Err(SchedulerError::ProcessIDNotFound(id)); } i += 1; } Ok(sleep_index) } pub fn sleep(&mut self, id: ProcId, time: u64) -> Result<(), SchedulerError> { match self.sleep_inner(id) { Ok(sid) => self .halted .push((ContextWake::Time(time), self.running.remove(sid))), Err(error) => return Err(error), } Ok(()) } pub fn schedule(&mut self, wc: WasmContext, cw: ContextWake) -> Result<(), SchedulerError> { if wc.proc_id != None { panic!("Already Scheduled with PROC_ID {}", wc.proc_id.unwrap()); } trace!("Scheduling WC with ProcID {}", self.next_proc_id); if cw == ContextWake::None { self.running.push(wc) } else { self.halted.push((cw, wc)); } self.next_proc_id += 1; Ok(()) } } #[derive(PartialEq)] pub enum ContextWake { /// Used when spawning a new process to have it instantly start None, Time(u64), ObjectEvent, } pub enum SchedulerError { ProcessIDNotFound(ProcId), AlreadyScheduled(), }