From e05be94c800101654cf471d233d3c26c32d226c0 Mon Sep 17 00:00:00 2001 From: chenqiuhao Date: Fri, 5 Oct 2018 12:01:00 +0800 Subject: [PATCH] finish the comment of the process --- crate/process/src/processor.rs | 133 ++++++++++++++++++++++++++++++--- crate/process/src/scheduler.rs | 36 ++++++++- crate/process/src/thread.rs | 54 ++++++++++--- 3 files changed, 204 insertions(+), 19 deletions(-) diff --git a/crate/process/src/processor.rs b/crate/process/src/processor.rs index 9083dad..80545e3 100644 --- a/crate/process/src/processor.rs +++ b/crate/process/src/processor.rs @@ -50,6 +50,13 @@ impl Process { // TODO: 除schedule()外的其它函数,应该只设置进程状态,不应调用schedule impl Processor_ { + + /* + ** @brief create a new Processor + ** @param init_context: T initiate context + ** scheduler: S the scheduler to use + ** @retval the Processor created + */ pub fn new(init_context: T, scheduler: S) -> Self { let init_proc = Process { pid: 0, @@ -70,15 +77,30 @@ impl Processor_ { } } + /* + ** @brief set the priority of current process + ** @param priority: u8 the priority to set + ** @retval none + */ pub fn set_priority(&mut self, priority: u8) { self.scheduler.set_priority(self.current_pid, priority); } + /* + ** @brief mark the current process to reschedule + ** @param none + ** @retval none + */ pub fn set_reschedule(&mut self) { let pid = self.current_pid; self.set_status(pid, Status::Ready); } + /* + ** @brief allocate the pid of the process + ** @param none + ** @retval the pid allocated + */ fn alloc_pid(&self) -> Pid { let mut next: Pid = 0; for &i in self.procs.keys() { @@ -91,6 +113,12 @@ impl Processor_ { return next; } + /* + ** @brief set the status of the process + ** @param pid: Pid the pid of process which needs to be set + ** status: Status the status to be set + ** @retval none + */ fn set_status(&mut self, pid: Pid, status: Status) { let status0 = self.get(pid).status.clone(); match (&status0, &status) { @@ -103,8 +131,12 @@ impl Processor_ { self.get_mut(pid).status = status; } - /// Called by timer. - /// Handle events. + /* + ** @brief Called by timer. + ** Handle events. + ** @param none + ** @retval none + */ pub fn tick(&mut self) { let current_pid = self.current_pid; if self.scheduler.tick(current_pid) { @@ -127,10 +159,20 @@ impl Processor_ { } } + /* + ** @brief get now time + ** @param none + ** @retval the time got + */ pub fn get_time(&self) -> usize { self.event_hub.get_time() } + /* + ** @brief add a new process + ** @param context: T the context fo the process + ** @retval the pid of new process + */ pub fn add(&mut self, context: T) -> Pid { let pid = self.alloc_pid(); let process = Process { @@ -144,8 +186,12 @@ impl Processor_ { pid } - /// Called every interrupt end - /// Do schedule ONLY IF current status != Running + /* + ** @brief Called every interrupt end + ** Do schedule ONLY IF current status != Running + ** @param none + ** @retval none + */ pub fn schedule(&mut self) { if self.get(self.current_pid).status == Status::Running { return; @@ -154,9 +200,13 @@ impl Processor_ { self.switch_to(pid); } - /// Switch process to `pid`, switch page table if necessary. - /// Store `rsp` and point it to target kernel stack. - /// The current status must be set before, and not be `Running`. + /* + ** @brief Switch process to `pid`, switch page table if necessary. + Store `rsp` and point it to target kernel stack. + The current status must be set before, and not be `Running`. + ** @param the pid of the process to switch + ** @retval none + */ fn switch_to(&mut self, pid: Pid) { // for debug print let pid0 = self.current_pid; @@ -180,23 +230,57 @@ impl Processor_ { unsafe { from.context.switch(&mut to.context); } } + /* + ** @brief get process by pid + ** @param pid: Pid the pid of the process + ** @retval the process struct + */ fn get(&self, pid: Pid) -> &Process { self.procs.get(&pid).unwrap() } + + /* + ** @brief get mut process struct by pid + ** @param pid: Pid the pid of the process + ** @retval the mut process struct + */ fn get_mut(&mut self, pid: Pid) -> &mut Process { self.procs.get_mut(&pid).unwrap() } + + /* + ** @brief get context of current process + ** @param none + ** @retval current context + */ pub fn current_context(&self) -> &T { &self.get(self.current_pid).context } + + /* + ** @brief get pid of current process + ** @param none + ** @retval current pid + */ pub fn current_pid(&self) -> Pid { self.current_pid } + /* + ** @brief kill a process by pid + ** @param pid: Pid the pid of the process to kill + ** @retval none + */ pub fn kill(&mut self, pid: Pid) { self.exit(pid, 0x1000); // TODO: error code for killed } + /* + ** @brief exit a process by pid + ** @param pid: Pid the pid to exit + ** error_code: ErrorCode the error code when exiting + ** @retval none + */ pub fn exit(&mut self, pid: Pid, error_code: ErrorCode) { info!("{} exit, code: {}", pid, error_code); self.set_status(pid, Status::Exited(error_code)); @@ -207,18 +291,40 @@ impl Processor_ { } } + /* + ** @brief let a process to sleep for a while + ** @param pid: Pid the pid of the process to sleep + ** time: usize the time to sleep + ** @retval none + */ pub fn sleep(&mut self, pid: Pid, time: usize) { self.set_status(pid, Status::Sleeping); self.event_hub.push(time, Event::Wakeup(pid)); } + + /* + ** @brief let a process to sleep until wake up + ** @param pid: Pid the pid of the process to sleep + ** @retval none + */ pub fn sleep_(&mut self, pid: Pid) { self.set_status(pid, Status::Sleeping); } + + /* + ** @brief wake up al sleeping process + ** @param pid: Pid the pid of the process to wake up + ** @retval none + */ pub fn wakeup_(&mut self, pid: Pid) { self.set_status(pid, Status::Ready); } - /// Let current process wait for another + /* + ** @brief Let current process wait for another + ** @param pid: Pid the pid of the process to wait for + ** @retval the result of wait + */ pub fn current_wait_for(&mut self, pid: Pid) -> WaitResult { info!("current {} wait for {:?}", self.current_pid, pid); if self.procs.values().filter(|&p| p.parent == self.current_pid).next().is_none() { @@ -236,7 +342,11 @@ impl Processor_ { WaitResult::Ok(pid, exit_code) } - /// Try to find a exited wait target + /* + ** @brief Try to find a exited wait target + ** @param pid: Pid the pid of the process to wait for + ** @retval the pid found or none + */ fn try_wait(&mut self, pid: Pid) -> Option { match pid { 0 => self.procs.values() @@ -246,6 +356,11 @@ impl Processor_ { } } + /* + ** @brief find one process which is waiting for the input process + ** @param pid: Pid the pid of the target process + ** @retval the pid of the waiting process or none + */ fn find_waiter(&self, pid: Pid) -> Option { self.procs.values().find(|&p| { p.status == Status::Waiting(pid) || diff --git a/crate/process/src/scheduler.rs b/crate/process/src/scheduler.rs index 4d8e696..cfc42a4 100644 --- a/crate/process/src/scheduler.rs +++ b/crate/process/src/scheduler.rs @@ -2,18 +2,51 @@ use alloc::{collections::BinaryHeap, vec::Vec}; type Pid = usize; -/// + +// implements of process scheduler pub trait Scheduler { + + /* + ** @brief add a new process + ** @param pid: Pid the pid of the process to add + ** @retval none + */ fn insert(&mut self, pid: Pid); + + /* + ** @brief remove a processs from the list + ** @param pid: Pid the pid of the process to remove + ** @retval none + */ fn remove(&mut self, pid: Pid); + + /* + ** @brief choose a process to run next + ** @param none + ** @retval Option the pid of the process to run or none + */ fn select(&mut self) -> Option; + + /* + ** @brief when a clock interrupt occurs, update the list and check whether need to reschedule + ** @param current: Pid the pid of the process which is running now + ** @retval bool if need to reschedule + */ fn tick(&mut self, current: Pid) -> bool; // need reschedule? + + /* + ** @brief set the priority of the process + ** @param pid: Pid the pid of the process to be set + ** priority: u8 the priority to be set + ** @retval none + */ fn set_priority(&mut self, pid: Pid, priority: u8); } pub use self::rr::RRScheduler; pub use self::stride::StrideScheduler; +// use round-robin scheduling mod rr { use super::*; @@ -106,6 +139,7 @@ mod rr { } } +// use stride scheduling mod stride { use super::*; diff --git a/crate/process/src/thread.rs b/crate/process/src/thread.rs index 1a93dd8..3e45c58 100644 --- a/crate/process/src/thread.rs +++ b/crate/process/src/thread.rs @@ -50,7 +50,11 @@ pub struct ThreadMod { } impl ThreadMod { - /// Gets a handle to the thread that invokes it. + /* + ** @brief Gets a handle to the thread that invokes it. + ** @param none + ** @retval the thread to get + */ pub fn current() -> Thread { Thread { pid: S::processor().current_pid(), @@ -58,7 +62,11 @@ impl ThreadMod { } } - /// Puts the current thread to sleep for the specified amount of time. + /* + ** @brief Puts the current thread to sleep for the specified amount of time. + ** @param dur: Duration the time to sleep + ** @retval none + */ pub fn sleep(dur: Duration) { let time = dur_to_ticks(dur); info!("sleep: {:?} ticks", time); @@ -72,7 +80,11 @@ impl ThreadMod { } } - /// Spawns a new thread, returning a JoinHandle for it. + /* + ** @brief Spawns a new thread, returning a JoinHandle for it. + ** @param f: F the thread to start + ** @retval JoinHandle the JoinHandle of the new thread + */ pub fn spawn(f: F) -> JoinHandle where F: Send + 'static + FnOnce() -> T, @@ -103,7 +115,11 @@ impl ThreadMod { } } - /// Cooperatively gives up a timeslice to the OS scheduler. + /* + ** @brief Cooperatively gives up a timeslice to the OS scheduler. + ** @param none + ** @retval none + */ pub fn yield_now() { info!("yield:"); let mut processor = S::processor(); @@ -111,7 +127,11 @@ impl ThreadMod { processor.schedule(); } - /// Blocks unless or until the current thread's token is made available. + /* + ** @brief Blocks unless or until the current thread's token is made available. + ** @param none + ** @retval none + */ pub fn park() { info!("park:"); let mut processor = S::processor(); @@ -128,12 +148,20 @@ pub struct Thread { } impl Thread { - /// Atomically makes the handle's token available if it is not already. + /* + ** @brief Atomically makes the handle's token available if it is not already. + ** @param none + ** @retval none + */ pub fn unpark(&self) { let mut processor = S::processor(); processor.wakeup_(self.pid); } - /// Gets the thread's unique identifier. + /* + ** @brief Gets the thread's unique identifier. + ** @param none + ** @retval usize the the thread's unique identifier + */ pub fn id(&self) -> usize { self.pid } @@ -146,11 +174,19 @@ pub struct JoinHandle { } impl JoinHandle { - /// Extracts a handle to the underlying thread. + /* + ** @brief Extracts a handle to the underlying thread. + ** @param none + ** @retval the thread of the handle + */ pub fn thread(&self) -> &Thread { &self.thread } - /// Waits for the associated thread to finish. + /* + ** @brief Waits for the associated thread to finish. + ** @param none + ** @retval Result the result of the associated thread + */ pub fn join(self) -> Result { let mut processor = S::processor(); match processor.current_wait_for(self.thread.pid) {