forked from AbleOS/ableos
105 lines
2.6 KiB
Rust
105 lines
2.6 KiB
Rust
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<WasmContext>,
|
|
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<usize, SchedulerError> {
|
|
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(),
|
|
}
|