Too late but it kinda works
This commit is contained in:
107
src/process.rs
Normal file
107
src/process.rs
Normal file
@@ -0,0 +1,107 @@
|
||||
use core::{arch::riscv64::wfi, time::Duration};
|
||||
|
||||
use alloc::{format, string::String};
|
||||
|
||||
use crate::{
|
||||
scheduler::{scheduler, ACTIVE_PID, PROCESSUS_COUNT, PROCESS_TABLE},
|
||||
time::elapsed_time_since_startup,
|
||||
};
|
||||
|
||||
const STACK_SIZE: usize = 4096;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum ProcessState {
|
||||
Active,
|
||||
Activable,
|
||||
Dead,
|
||||
Asleep,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct ExecutionContext {
|
||||
pub ra: *const usize,
|
||||
pub sp: *const usize,
|
||||
pub gp: usize,
|
||||
pub tp: usize,
|
||||
pub a: [usize; 8],
|
||||
pub t: [usize; 7],
|
||||
pub s: [usize; 11],
|
||||
pub mepc: usize,
|
||||
pub mstatus: usize,
|
||||
}
|
||||
|
||||
pub struct Process {
|
||||
pub pid: i64,
|
||||
pub name: String,
|
||||
pub state: ProcessState,
|
||||
pub wake_time: Duration,
|
||||
pub ctx: ExecutionContext,
|
||||
pub entry_point: Option<extern "C" fn()>,
|
||||
pub stack: [usize; STACK_SIZE],
|
||||
}
|
||||
|
||||
impl core::fmt::Debug for Process {
|
||||
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
|
||||
f.debug_struct("Process")
|
||||
.field("pid", &self.pid)
|
||||
.field("name", &self.name)
|
||||
.field("state", &self.state)
|
||||
.field("wake_time", &self.wake_time)
|
||||
.field("ctx", &self.ctx)
|
||||
.field("entry_point", &self.entry_point)
|
||||
.field("stack", &format!("[_; {}]", STACK_SIZE))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_processus<T: Into<String>>(code: extern "C" fn(), name: T) -> i64 {
|
||||
let mut next_pid = 0;
|
||||
while next_pid < PROCESSUS_COUNT
|
||||
&& unsafe { PROCESS_TABLE[next_pid].state != ProcessState::Dead }
|
||||
{
|
||||
next_pid += 1;
|
||||
}
|
||||
|
||||
if next_pid >= PROCESSUS_COUNT {
|
||||
return -1;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
PROCESS_TABLE[next_pid].pid = next_pid as i64;
|
||||
PROCESS_TABLE[next_pid].name = name.into();
|
||||
PROCESS_TABLE[next_pid].state = ProcessState::Activable;
|
||||
PROCESS_TABLE[next_pid].entry_point = Some(code);
|
||||
PROCESS_TABLE[next_pid].ctx.a[0] = code as usize;
|
||||
PROCESS_TABLE[next_pid].ctx.ra = processus_launcher as *const _;
|
||||
PROCESS_TABLE[next_pid].ctx.sp = &raw const PROCESS_TABLE[next_pid].stack[STACK_SIZE - 1];
|
||||
}
|
||||
|
||||
next_pid as i64
|
||||
}
|
||||
|
||||
extern "C" fn processus_launcher(code: extern "C" fn()) {
|
||||
code();
|
||||
terminate_processus();
|
||||
}
|
||||
|
||||
fn terminate_processus() {
|
||||
unsafe {
|
||||
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Dead;
|
||||
}
|
||||
unsafe {
|
||||
wfi();
|
||||
}
|
||||
// scheduler();
|
||||
}
|
||||
|
||||
pub fn sleep(duration: Duration) {
|
||||
unsafe {
|
||||
PROCESS_TABLE[ACTIVE_PID].wake_time = elapsed_time_since_startup() + duration;
|
||||
PROCESS_TABLE[ACTIVE_PID].state = ProcessState::Asleep;
|
||||
}
|
||||
unsafe {
|
||||
wfi();
|
||||
}
|
||||
// scheduler();
|
||||
}
|
||||
Reference in New Issue
Block a user