ableos/kernel/src/schedule.rs

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(),
}