86 lines
2.2 KiB
Rust
86 lines
2.2 KiB
Rust
use core::{arch::riscv64::wfi, array, cell::LazyCell, time::Duration};
|
|
|
|
use alloc::string::String;
|
|
use log::info;
|
|
|
|
use crate::{
|
|
process::{create_process, ExecutionContext, Process, ProcessState},
|
|
time,
|
|
};
|
|
|
|
pub const PROCESS_COUNT: usize = 16;
|
|
|
|
pub static mut ACTIVE_PID: usize = 0;
|
|
pub static mut PROCESS_TABLE: LazyCell<[Process; PROCESS_COUNT]> = LazyCell::new(|| {
|
|
array::from_fn(|_| Process {
|
|
pid: -1,
|
|
name: String::new(),
|
|
state: ProcessState::Dead,
|
|
wake_time: Duration::new(0, 0),
|
|
ctx: ExecutionContext {
|
|
ra: core::ptr::null(),
|
|
sp: core::ptr::null(),
|
|
gp: 0,
|
|
tp: 0,
|
|
a: [0; _],
|
|
t: [0; _],
|
|
s: [0; _],
|
|
mepc: core::ptr::null(),
|
|
mstatus: 0,
|
|
},
|
|
stack: [0; _],
|
|
entry: None,
|
|
})
|
|
});
|
|
|
|
pub fn idle() {
|
|
loop {
|
|
// write_string_temp("idle");
|
|
// info!("idle");
|
|
unsafe {
|
|
wfi();
|
|
}
|
|
}
|
|
}
|
|
|
|
pub fn scheduler_init() {
|
|
info!("scheduler init");
|
|
for pid in 0..PROCESS_COUNT {
|
|
unsafe {
|
|
PROCESS_TABLE[pid].state = ProcessState::Dead;
|
|
}
|
|
}
|
|
|
|
create_process(&idle, "idle");
|
|
unsafe {
|
|
PROCESS_TABLE[0].state = ProcessState::Active;
|
|
}
|
|
}
|
|
|
|
pub fn scheduler_without_ret(interrupt_state: &mut *mut ExecutionContext) {
|
|
// info!("scheduler");
|
|
unsafe {
|
|
let prev_pid = ACTIVE_PID;
|
|
PROCESS_TABLE[prev_pid].ctx = **interrupt_state;
|
|
|
|
if PROCESS_TABLE[prev_pid].state == ProcessState::Active {
|
|
PROCESS_TABLE[prev_pid].state = ProcessState::Activable;
|
|
}
|
|
|
|
loop {
|
|
if PROCESS_TABLE[ACTIVE_PID].state == ProcessState::Asleep
|
|
&& time::elapsed_time_since_startup() > PROCESS_TABLE[ACTIVE_PID].wake_time
|
|
{
|
|
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Activable;
|
|
}
|
|
ACTIVE_PID = (ACTIVE_PID + 1) % PROCESS_COUNT;
|
|
if PROCESS_TABLE[ACTIVE_PID].state == ProcessState::Activable {
|
|
break;
|
|
}
|
|
}
|
|
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Active;
|
|
|
|
*interrupt_state = &raw mut PROCESS_TABLE[ACTIVE_PID].ctx
|
|
}
|
|
}
|