ableos/kernel/src/scheduler.rs

77 lines
2.3 KiB
Rust
Raw Normal View History

use {
alloc::{collections::VecDeque, rc::Rc, slice, vec::Vec},
hbvm::validate::validate,
};
2023-08-22 08:31:28 -05:00
use {crate::host::TrapHandler, hbvm::Vm};
2023-07-13 03:41:15 -05:00
const TIMER_QUOTIENT: usize = 100;
2023-06-26 07:55:37 -05:00
pub struct Scheduler<'a> {
data: VecDeque<Vm<'a, TrapHandler, TIMER_QUOTIENT>>,
2023-06-26 07:55:37 -05:00
}
// NOTE: This is a very simple schduler and it sucks and should be replaced with a better one
// Written By Yours Truly: Munir
2023-06-26 07:55:37 -05:00
impl Scheduler<'_> {
pub fn new() -> Self {
Self {
data: VecDeque::new(),
}
}
pub fn new_process(&mut self, program: Vec<u8>) {
let prog = program.clone();
let prog_arc = Rc::new(prog);
let binding = Rc::try_unwrap(prog_arc).ok().unwrap();
#[allow(clippy::redundant_else)]
if let Err(e) = validate(&program.as_slice()) {
log::error!("Program validation error: {e:?}");
} else {
log::info!("valid program");
unsafe {
let slice = slice::from_raw_parts(binding.as_ptr(), binding.len());
let mut vm = Vm::new_unchecked(&*slice, TrapHandler);
vm.memory.insert_test_page();
self.data.push_front(vm);
}
}
}
pub fn run(&mut self) -> ! {
loop {
// If there are no programs to run then sleep.
if self.data.is_empty() {
2023-07-15 07:47:46 -05:00
use crate::arch::spin_loop;
spin_loop();
}
let mut prog = self.data.pop_front().unwrap();
let ret = prog.run();
match ret {
Ok(oki) => match oki {
2023-08-22 08:31:28 -05:00
hbvm::VmRunOk::End => {
log::info!(
"Program ended. {} programs remaining.",
// Add one here because we pop a program
self.data.len() + 1
)
}
2023-08-22 08:31:28 -05:00
hbvm::VmRunOk::Timer => {
log::info!("Timer exhausted. Scheduled program");
self.data.push_back(prog);
}
2023-08-22 08:31:28 -05:00
hbvm::VmRunOk::Ecall => {
// panic!();
log::info!("{:?}", prog.registers);
self.data.push_back(prog);
}
},
Err(_) => {}
}
2023-07-11 03:02:40 -05:00
}
}
2023-06-26 07:55:37 -05:00
}