parent
0553d3374d
commit
6e157ee97d
@ -0,0 +1,50 @@
|
|||||||
|
use super::*;
|
||||||
|
use memory::Stack;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Process {
|
||||||
|
pub(in process) pid: Pid,
|
||||||
|
name: &'static str,
|
||||||
|
kstack: Stack,
|
||||||
|
// page_table: Box<PageTable>,
|
||||||
|
pub(in process) status: Status,
|
||||||
|
pub(in process) rsp: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub type Pid = usize;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub enum Status {
|
||||||
|
Ready, Running, Sleeping(usize), Exited
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Process {
|
||||||
|
/// Make a new kernel thread
|
||||||
|
pub fn new(name: &'static str, entry: extern fn(), mc: &mut MemoryController) -> Self {
|
||||||
|
let kstack = mc.alloc_stack(7).unwrap();
|
||||||
|
let rsp = unsafe{ (kstack.top() as *mut TrapFrame).offset(-1) } as usize;
|
||||||
|
|
||||||
|
let tf = unsafe{ &mut *(rsp as *mut TrapFrame) };
|
||||||
|
*tf = TrapFrame::new_kernel_thread(entry, kstack.top());
|
||||||
|
|
||||||
|
Process {
|
||||||
|
pid: 0,
|
||||||
|
name,
|
||||||
|
kstack,
|
||||||
|
status: Status::Ready,
|
||||||
|
rsp,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// Make the first kernel thread `initproc`
|
||||||
|
/// Should be called only once
|
||||||
|
pub fn new_init(mc: &mut MemoryController) -> Self {
|
||||||
|
assert_has_not_been_called!();
|
||||||
|
Process {
|
||||||
|
pid: 0,
|
||||||
|
name: "init",
|
||||||
|
kstack: mc.kernel_stack.take().unwrap(),
|
||||||
|
status: Status::Running,
|
||||||
|
rsp: 0, // will be set at first schedule
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
use alloc::BTreeMap;
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Processor {
|
||||||
|
procs: BTreeMap<Pid, Process>,
|
||||||
|
current_pid: Pid,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Processor {
|
||||||
|
pub fn new(mc: &mut MemoryController) -> Self {
|
||||||
|
Processor {
|
||||||
|
procs: BTreeMap::<Pid, Process>::new(),
|
||||||
|
current_pid: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn alloc_pid(&self) -> Pid {
|
||||||
|
let mut next: Pid = 0;
|
||||||
|
for &i in self.procs.keys() {
|
||||||
|
if i != next {
|
||||||
|
return next;
|
||||||
|
} else {
|
||||||
|
next = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn add(&mut self, mut process: Process) {
|
||||||
|
let pid = self.alloc_pid();
|
||||||
|
process.pid = pid;
|
||||||
|
self.procs.insert(pid, process);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn schedule(&mut self, rsp: &mut usize) {
|
||||||
|
let pid = self.find_next();
|
||||||
|
self.switch_to(pid, rsp);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn find_next(&self) -> Pid {
|
||||||
|
*self.procs.keys()
|
||||||
|
.find(|&&i| i > self.current_pid)
|
||||||
|
.unwrap_or(self.procs.keys().nth(0).unwrap())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn switch_to(&mut self, pid: Pid, rsp: &mut usize) {
|
||||||
|
// for debug print
|
||||||
|
let pid0 = self.current_pid;
|
||||||
|
let rsp0 = *rsp;
|
||||||
|
|
||||||
|
if pid == self.current_pid {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let current = self.procs.get_mut(&self.current_pid).unwrap();
|
||||||
|
current.status = Status::Ready;
|
||||||
|
current.rsp = *rsp;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
let process = self.procs.get_mut(&pid).unwrap();
|
||||||
|
process.status = Status::Running;
|
||||||
|
*rsp = process.rsp;
|
||||||
|
// TODO switch page table
|
||||||
|
}
|
||||||
|
self.current_pid = pid;
|
||||||
|
debug!("Processor: switch from {} to {}\n rsp: {:#x} -> {:#x}", pid0, pid, rsp0, rsp);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue