Try loading code at runtime
This commit is contained in:
107
src/process.rs
107
src/process.rs
@@ -1,107 +0,0 @@
|
||||
use core::{arch::riscv64::wfi, time::Duration};
|
||||
|
||||
use alloc::{format, string::String};
|
||||
|
||||
use crate::{
|
||||
scheduler::{ACTIVE_PID, PROCESS_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 u64,
|
||||
pub sp: *const u64,
|
||||
pub gp: u64,
|
||||
pub tp: u64,
|
||||
pub a: [u64; 8],
|
||||
pub t: [u64; 7],
|
||||
pub s: [u64; 12],
|
||||
pub mepc: *const u64,
|
||||
pub mstatus: u64,
|
||||
}
|
||||
|
||||
pub struct Process {
|
||||
pub pid: i64,
|
||||
pub name: String,
|
||||
pub state: ProcessState,
|
||||
pub entry: Option<fn()>,
|
||||
pub wake_time: Duration,
|
||||
pub ctx: ExecutionContext,
|
||||
pub stack: [u64; 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("stack", &format!("[_; {}]", STACK_SIZE))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_process<T: Into<String>>(code: fn(), name: T) -> i64 {
|
||||
let mut next_pid = 0;
|
||||
while next_pid < PROCESS_COUNT && unsafe { PROCESS_TABLE[next_pid].state != ProcessState::Dead }
|
||||
{
|
||||
next_pid += 1;
|
||||
}
|
||||
|
||||
if next_pid >= PROCESS_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 = Some(code);
|
||||
PROCESS_TABLE[next_pid].ctx.a[0] =
|
||||
PROCESS_TABLE[next_pid].entry.as_ref().unwrap_unchecked() as *const fn() as u64;
|
||||
PROCESS_TABLE[next_pid].ctx.mepc = process_launcher as *const _;
|
||||
PROCESS_TABLE[next_pid].ctx.mstatus = 1 << 1 | 1 << 5;
|
||||
PROCESS_TABLE[next_pid].ctx.sp = &raw const PROCESS_TABLE[next_pid].stack[STACK_SIZE - 1];
|
||||
}
|
||||
|
||||
next_pid as i64
|
||||
}
|
||||
|
||||
extern "C" fn process_launcher(code: *const fn()) {
|
||||
unsafe { (*code)() };
|
||||
terminate_process();
|
||||
}
|
||||
|
||||
fn terminate_process() {
|
||||
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