diff --git a/crate/process/src/process_manager.rs b/crate/process/src/process_manager.rs index dd8dab5..37a9652 100644 --- a/crate/process/src/process_manager.rs +++ b/crate/process/src/process_manager.rs @@ -71,6 +71,11 @@ impl ProcessManager { self.scheduler.lock().tick(pid) } + /// Set the priority of process `pid` + pub fn set_priority(&self, pid: Pid, priority: u8) { + self.scheduler.lock().set_priority(pid, priority); + } + /// Called by Processor to get a process to run. /// The manager first mark it `Running`, /// then take out and return its Context. diff --git a/crate/process/src/processor.rs b/crate/process/src/processor.rs index 4fc3e18..c1432ca 100644 --- a/crate/process/src/processor.rs +++ b/crate/process/src/processor.rs @@ -78,6 +78,10 @@ impl Processor { self.inner().proc.as_ref().unwrap().0 } + pub fn context(&self) -> &Context { + &*self.inner().proc.as_ref().unwrap().1 + } + pub fn manager(&self) -> &ProcessManager { &*self.inner().manager } diff --git a/kernel/src/process/context.rs b/kernel/src/process/context.rs index e078219..dcc53f5 100644 --- a/kernel/src/process/context.rs +++ b/kernel/src/process/context.rs @@ -12,13 +12,8 @@ pub struct ContextImpl { impl Context for ContextImpl { unsafe fn switch_to(&mut self, target: &mut Context) { - use core::raw::TraitObject; use core::mem::transmute; - - // Cast &mut Context -> &mut ContextImpl - let raw: TraitObject = transmute(target); - let target = &mut *(raw.data as *mut ContextImpl); - + let (target, _): (&mut ContextImpl, *const ()) = transmute(target); self.arch.switch(&mut target.arch); } } diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 0e13b33..3f143da 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -19,7 +19,7 @@ pub fn init() { extern fn idle(_arg: usize) -> ! { loop { cpu::halt(); } } - for i in 0..MAX_CPU_NUM { + for i in 0..4 { manager.add(ContextImpl::new_kernel(idle, i)); } diff --git a/kernel/src/syscall.rs b/kernel/src/syscall.rs index 5c48ecf..6dbd056 100644 --- a/kernel/src/syscall.rs +++ b/kernel/src/syscall.rs @@ -58,7 +58,11 @@ fn sys_close(fd: usize) -> i32 { /// Fork the current process. Return the child's PID. fn sys_fork(tf: &TrapFrame) -> i32 { - unimplemented!(); + use core::mem::transmute; + let (context, _): (&ContextImpl, *const ()) = unsafe { transmute(processor().context()) }; + let pid = processor().manager().add(context.fork(tf)); + info!("fork: {} -> {}", thread::current().id(), pid); + pid as i32 } /// Wait the process exit. @@ -85,7 +89,7 @@ fn sys_getpid() -> i32 { /// Exit the current process fn sys_exit(exit_code: usize) -> i32 { - let pid = processor().pid(); + let pid = thread::current().id(); processor().manager().set_status(pid, Status::Exited(exit_code)); processor().yield_now(); 0 @@ -102,7 +106,8 @@ fn sys_get_time() -> i32 { } fn sys_lab6_set_priority(priority: usize) -> i32 { - unimplemented!(); + let pid = thread::current().id(); + processor().manager().set_priority(pid, priority as u8); 0 }