From 5bffce787b87f88600937d6956588399cf60f5f1 Mon Sep 17 00:00:00 2001 From: WangRunji Date: Thu, 24 Jan 2019 19:03:45 +0800 Subject: [PATCH] rename 'process' crate to 'thread' --- crate/{process => thread}/Cargo.toml | 3 +- crate/{process => thread}/build.rs | 0 crate/{process => thread}/src/event_hub.rs | 0 crate/{process => thread}/src/interrupt.rs | 2 + crate/{process => thread}/src/lib.rs | 6 +- crate/{process => thread}/src/processor.rs | 16 +- crate/{process => thread}/src/scheduler.rs | 0 .../thread.rs => thread/src/std_thread.rs} | 8 +- .../src/thread_pool.rs} | 141 +++++++++--------- kernel/Cargo.lock | 4 +- kernel/Cargo.toml | 2 +- kernel/src/lib.rs | 2 +- kernel/src/process/context.rs | 2 +- kernel/src/process/mod.rs | 4 +- kernel/src/shell.rs | 1 + kernel/src/trap.rs | 2 +- 16 files changed, 97 insertions(+), 96 deletions(-) rename crate/{process => thread}/Cargo.toml (57%) rename crate/{process => thread}/build.rs (100%) rename crate/{process => thread}/src/event_hub.rs (100%) rename crate/{process => thread}/src/interrupt.rs (96%) rename crate/{process => thread}/src/lib.rs (81%) rename crate/{process => thread}/src/processor.rs (89%) rename crate/{process => thread}/src/scheduler.rs (100%) rename crate/{process/src/thread.rs => thread/src/std_thread.rs} (98%) rename crate/{process/src/process_manager.rs => thread/src/thread_pool.rs} (53%) diff --git a/crate/process/Cargo.toml b/crate/thread/Cargo.toml similarity index 57% rename from crate/process/Cargo.toml rename to crate/thread/Cargo.toml index 29d4995..a228acf 100644 --- a/crate/process/Cargo.toml +++ b/crate/thread/Cargo.toml @@ -1,7 +1,8 @@ [package] -name = "rcore-process" +name = "rcore-thread" version = "0.1.0" authors = ["WangRunji "] +description = "Bare-metal thread scheduler and executor" edition = "2018" [dependencies] diff --git a/crate/process/build.rs b/crate/thread/build.rs similarity index 100% rename from crate/process/build.rs rename to crate/thread/build.rs diff --git a/crate/process/src/event_hub.rs b/crate/thread/src/event_hub.rs similarity index 100% rename from crate/process/src/event_hub.rs rename to crate/thread/src/event_hub.rs diff --git a/crate/process/src/interrupt.rs b/crate/thread/src/interrupt.rs similarity index 96% rename from crate/process/src/interrupt.rs rename to crate/thread/src/interrupt.rs index 6e238be..e23eb12 100644 --- a/crate/process/src/interrupt.rs +++ b/crate/thread/src/interrupt.rs @@ -1,3 +1,5 @@ +//! Enable and disable interrupt for each architecture. + #[inline(always)] #[cfg(target_arch = "x86_64")] pub unsafe fn disable_and_store() -> usize { diff --git a/crate/process/src/lib.rs b/crate/thread/src/lib.rs similarity index 81% rename from crate/process/src/lib.rs rename to crate/thread/src/lib.rs index 764cdb6..bd0d394 100644 --- a/crate/process/src/lib.rs +++ b/crate/thread/src/lib.rs @@ -9,12 +9,12 @@ extern crate alloc; -mod process_manager; +mod thread_pool; mod processor; pub mod scheduler; -pub mod thread; +pub mod std_thread; mod event_hub; mod interrupt; -pub use crate::process_manager::*; +pub use crate::thread_pool::*; pub use crate::processor::Processor; diff --git a/crate/process/src/processor.rs b/crate/thread/src/processor.rs similarity index 89% rename from crate/process/src/processor.rs rename to crate/thread/src/processor.rs index e316324..27a3ca2 100644 --- a/crate/process/src/processor.rs +++ b/crate/thread/src/processor.rs @@ -2,10 +2,10 @@ use alloc::boxed::Box; use alloc::sync::Arc; use log::*; use core::cell::UnsafeCell; -use crate::process_manager::*; +use crate::thread_pool::*; use crate::interrupt; -/// Process executor +/// Thread executor /// /// Per-CPU struct. Defined at global. /// Only accessed by associated CPU with interrupt disabled. @@ -18,9 +18,9 @@ unsafe impl Sync for Processor {} struct ProcessorInner { id: usize, - proc: Option<(Pid, Box)>, + proc: Option<(Tid, Box)>, loop_context: Box, - manager: Arc, + manager: Arc, } impl Processor { @@ -28,7 +28,7 @@ impl Processor { Processor { inner: UnsafeCell::new(None) } } - pub unsafe fn init(&self, id: usize, context: Box, manager: Arc) { + pub unsafe fn init(&self, id: usize, context: Box, manager: Arc) { *self.inner.get() = Some(ProcessorInner { id, proc: None, @@ -76,7 +76,7 @@ impl Processor { } } - pub fn pid(&self) -> Pid { + pub fn tid(&self) -> Tid { self.inner().proc.as_ref().unwrap().0 } @@ -84,13 +84,13 @@ impl Processor { &*self.inner().proc.as_ref().unwrap().1 } - pub fn manager(&self) -> &ProcessManager { + pub fn manager(&self) -> &ThreadPool { &*self.inner().manager } pub fn tick(&self) { let flags = unsafe { interrupt::disable_and_store() }; - let need_reschedule = self.manager().tick(self.pid()); + let need_reschedule = self.manager().tick(self.tid()); unsafe { interrupt::restore(flags); } if need_reschedule { diff --git a/crate/process/src/scheduler.rs b/crate/thread/src/scheduler.rs similarity index 100% rename from crate/process/src/scheduler.rs rename to crate/thread/src/scheduler.rs diff --git a/crate/process/src/thread.rs b/crate/thread/src/std_thread.rs similarity index 98% rename from crate/process/src/thread.rs rename to crate/thread/src/std_thread.rs index 7657492..e59a559 100644 --- a/crate/process/src/thread.rs +++ b/crate/thread/src/std_thread.rs @@ -1,4 +1,4 @@ -//! Thread std-like interface +//! `std::thread`-like interface //! //! Based on Processor. Used in kernel. //! @@ -11,7 +11,7 @@ use core::marker::PhantomData; use core::time::Duration; use log::*; use crate::processor::*; -use crate::process_manager::*; +use crate::thread_pool::*; #[linkage = "weak"] #[no_mangle] @@ -30,7 +30,7 @@ fn new_kernel_context(_entry: extern fn(usize) -> !, _arg: usize) -> Box Thread { - Thread { pid: processor().pid() } + Thread { pid: processor().tid() } } /// Puts the current thread to sleep for the specified amount of time. @@ -160,7 +160,7 @@ impl JoinHandle { } } /// Force construct a JoinHandle struct - pub unsafe fn _of(pid: Pid) -> JoinHandle { + pub unsafe fn _of(pid: Tid) -> JoinHandle { JoinHandle { thread: Thread { pid }, mark: PhantomData, diff --git a/crate/process/src/process_manager.rs b/crate/thread/src/thread_pool.rs similarity index 53% rename from crate/process/src/process_manager.rs rename to crate/thread/src/thread_pool.rs index 2ca17b5..7043b55 100644 --- a/crate/process/src/process_manager.rs +++ b/crate/thread/src/thread_pool.rs @@ -5,17 +5,15 @@ use log::*; use crate::scheduler::Scheduler; use crate::event_hub::EventHub; -struct Process { - #[allow(dead_code)] - id: Pid, +struct Thread { status: Status, status_after_stop: Status, context: Option>, - parent: Pid, - children: Vec, + parent: Tid, + children: Vec, } -pub type Pid = usize; +pub type Tid = usize; type ExitCode = usize; #[derive(Debug, Clone, Eq, PartialEq)] @@ -23,37 +21,37 @@ pub enum Status { Ready, Running(usize), Sleeping, - Waiting(Pid), + Waiting(Tid), /// aka ZOMBIE. Its context was dropped. Exited(ExitCode), } #[derive(Eq, PartialEq)] enum Event { - Wakeup(Pid), + Wakeup(Tid), } pub trait Context { unsafe fn switch_to(&mut self, target: &mut Context); } -pub struct ProcessManager { - procs: Vec>>, +pub struct ThreadPool { + threads: Vec>>, scheduler: Mutex>, event_hub: Mutex>, } -impl ProcessManager { +impl ThreadPool { pub fn new(scheduler: Box, max_proc_num: usize) -> Self { - ProcessManager { - procs: new_vec_default(max_proc_num), + ThreadPool { + threads: new_vec_default(max_proc_num), scheduler: Mutex::new(scheduler), event_hub: Mutex::new(EventHub::new()), } } - fn alloc_pid(&self) -> Pid { - for (i, proc) in self.procs.iter().enumerate() { + fn alloc_tid(&self) -> Tid { + for (i, proc) in self.threads.iter().enumerate() { if proc.lock().is_none() { return i; } @@ -62,82 +60,81 @@ impl ProcessManager { } /// Add a new process - pub fn add(&self, context: Box, parent: Pid) -> Pid { - let pid = self.alloc_pid(); - *(&self.procs[pid]).lock() = Some(Process { - id: pid, + pub fn add(&self, context: Box, parent: Tid) -> Tid { + let tid = self.alloc_tid(); + *(&self.threads[tid]).lock() = Some(Thread { status: Status::Ready, status_after_stop: Status::Ready, context: Some(context), parent, children: Vec::new(), }); - self.scheduler.lock().insert(pid); - self.procs[parent].lock().as_mut().expect("invalid parent proc") - .children.push(pid); - pid + self.scheduler.lock().insert(tid); + self.threads[parent].lock().as_mut().expect("invalid parent proc") + .children.push(tid); + tid } - /// Make process `pid` time slice -= 1. + /// Make process `tid` time slice -= 1. /// Return true if time slice == 0. /// Called by timer interrupt handler. - pub fn tick(&self, pid: Pid) -> bool { + pub fn tick(&self, tid: Tid) -> bool { let mut event_hub = self.event_hub.lock(); event_hub.tick(); while let Some(event) = event_hub.pop() { match event { - Event::Wakeup(pid) => self.set_status(pid, Status::Ready), + Event::Wakeup(tid) => self.set_status(tid, Status::Ready), } } - self.scheduler.lock().tick(pid) + self.scheduler.lock().tick(tid) } - /// Set the priority of process `pid` - pub fn set_priority(&self, pid: Pid, priority: u8) { - self.scheduler.lock().set_priority(pid, priority); + /// Set the priority of process `tid` + pub fn set_priority(&self, tid: Tid, priority: u8) { + self.scheduler.lock().set_priority(tid, priority); } /// Called by Processor to get a process to run. /// The manager first mark it `Running`, /// then take out and return its Context. - pub fn run(&self, cpu_id: usize) -> (Pid, Box) { + pub fn run(&self, cpu_id: usize) -> (Tid, Box) { let mut scheduler = self.scheduler.lock(); - let pid = scheduler.select() + let tid = scheduler.select() .expect("failed to select a runnable process"); - scheduler.remove(pid); - let mut proc_lock = self.procs[pid].lock(); + scheduler.remove(tid); + let mut proc_lock = self.threads[tid].lock(); let mut proc = proc_lock.as_mut().expect("process not exist"); proc.status = Status::Running(cpu_id); - (pid, proc.context.take().expect("context not exist")) + (tid, proc.context.take().expect("context not exist")) } /// Called by Processor to finish running a process /// and give its context back. - pub fn stop(&self, pid: Pid, context: Box) { - let mut proc_lock = self.procs[pid].lock(); + pub fn stop(&self, tid: Tid, context: Box) { + let mut proc_lock = self.threads[tid].lock(); let mut proc = proc_lock.as_mut().expect("process not exist"); proc.status = proc.status_after_stop.clone(); proc.status_after_stop = Status::Ready; proc.context = Some(context); match proc.status { - Status::Ready => self.scheduler.lock().insert(pid), - Status::Exited(_) => self.exit_handler(pid, proc), + Status::Ready => self.scheduler.lock().insert(tid), + Status::Exited(_) => self.exit_handler(tid, proc), _ => {} } } /// Switch the status of a process. /// Insert/Remove it to/from scheduler if necessary. - fn set_status(&self, pid: Pid, status: Status) { - let mut proc_lock = self.procs[pid].lock(); + fn set_status(&self, tid: Tid, status: Status) { + let mut proc_lock = self.threads[tid].lock(); let mut proc = proc_lock.as_mut().expect("process not exist"); - trace!("process {} {:?} -> {:?}", pid, proc.status, status); + trace!("process {} {:?} -> {:?}", tid, proc.status, status); match (&proc.status, &status) { (Status::Ready, Status::Ready) => return, - (Status::Ready, _) => self.scheduler.lock().remove(pid), + (Status::Ready, _) => self.scheduler.lock().remove(tid), (Status::Exited(_), _) => panic!("can not set status for a exited process"), - (Status::Sleeping, Status::Exited(_)) => self.event_hub.lock().remove(Event::Wakeup(pid)), - (_, Status::Ready) => self.scheduler.lock().insert(pid), + (Status::Sleeping, Status::Exited(_)) => self.event_hub.lock().remove(Event::Wakeup(tid)), + (_, Status::Ready) => self.scheduler.lock().insert(tid), _ => {} } match proc.status { @@ -145,19 +142,19 @@ impl ProcessManager { _ => proc.status = status, } match proc.status { - Status::Exited(_) => self.exit_handler(pid, proc), + Status::Exited(_) => self.exit_handler(tid, proc), _ => {} } } - pub fn get_status(&self, pid: Pid) -> Option { - self.procs[pid].lock().as_ref().map(|p| p.status.clone()) + pub fn get_status(&self, tid: Tid) -> Option { + self.threads[tid].lock().as_ref().map(|p| p.status.clone()) } - /// Remove an exited proc `pid`. + /// Remove an exited proc `tid`. /// Its all children will be set parent to 0. - pub fn remove(&self, pid: Pid) { - let mut proc_lock = self.procs[pid].lock(); + pub fn remove(&self, tid: Tid) { + let mut proc_lock = self.threads[tid].lock(); let proc = proc_lock.as_ref().expect("process not exist"); match proc.status { Status::Exited(_) => {} @@ -165,49 +162,49 @@ impl ProcessManager { } // orphan procs for child in proc.children.iter() { - (&self.procs[*child]).lock().as_mut().expect("process not exist").parent = 0; + (&self.threads[*child]).lock().as_mut().expect("process not exist").parent = 0; } // remove self from parent's children list - self.procs[proc.parent].lock().as_mut().expect("process not exist") - .children.retain(|&i| i != pid); - // release the pid + self.threads[proc.parent].lock().as_mut().expect("process not exist") + .children.retain(|&i| i != tid); + // release the tid *proc_lock = None; } - /// Sleep `pid` for `time` ticks. + /// Sleep `tid` for `time` ticks. /// `time` == 0 means sleep forever - pub fn sleep(&self, pid: Pid, time: usize) { - self.set_status(pid, Status::Sleeping); + pub fn sleep(&self, tid: Tid, time: usize) { + self.set_status(tid, Status::Sleeping); if time != 0 { - self.event_hub.lock().push(time, Event::Wakeup(pid)); + self.event_hub.lock().push(time, Event::Wakeup(tid)); } } - pub fn wakeup(&self, pid: Pid) { - self.set_status(pid, Status::Ready); + pub fn wakeup(&self, tid: Tid) { + self.set_status(tid, Status::Ready); } - pub fn wait(&self, pid: Pid, target: Pid) { - self.set_status(pid, Status::Waiting(target)); + pub fn wait(&self, tid: Tid, target: Tid) { + self.set_status(tid, Status::Waiting(target)); } - pub fn wait_child(&self, pid: Pid) { - self.set_status(pid, Status::Waiting(0)); + pub fn wait_child(&self, tid: Tid) { + self.set_status(tid, Status::Waiting(0)); } - pub fn get_children(&self, pid: Pid) -> Vec { - self.procs[pid].lock().as_ref().expect("process not exist").children.clone() + pub fn get_children(&self, tid: Tid) -> Vec { + self.threads[tid].lock().as_ref().expect("process not exist").children.clone() } - pub fn exit(&self, pid: Pid, code: ExitCode) { - // NOTE: if `pid` is running, status change will be deferred. - self.set_status(pid, Status::Exited(code)); + pub fn exit(&self, tid: Tid, code: ExitCode) { + // NOTE: if `tid` is running, status change will be deferred. + self.set_status(tid, Status::Exited(code)); } /// Called when a process exit - fn exit_handler(&self, pid: Pid, proc: &mut Process) { + fn exit_handler(&self, tid: Tid, proc: &mut Thread) { // wakeup parent if waiting let parent = proc.parent; match self.get_status(parent).expect("process not exist") { - Status::Waiting(target) if target == pid || target == 0 => self.wakeup(parent), + Status::Waiting(target) if target == tid || target == 0 => self.wakeup(parent), _ => {} } // drop its context diff --git a/kernel/Cargo.lock b/kernel/Cargo.lock index 0d41c34..bb25132 100644 --- a/kernel/Cargo.lock +++ b/kernel/Cargo.lock @@ -248,7 +248,7 @@ dependencies = [ "pc-keyboard 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "raw-cpuid 6.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "rcore-memory 0.1.0", - "rcore-process 0.1.0", + "rcore-thread 0.1.0", "riscv 0.3.0 (git+https://github.com/riscv-and-rust-and-decaf/riscv)", "simple-filesystem 0.1.0 (git+https://github.com/wangrunji0408/SimpleFileSystem-Rust)", "smoltcp 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -267,7 +267,7 @@ dependencies = [ ] [[package]] -name = "rcore-process" +name = "rcore-thread" version = "0.1.0" dependencies = [ "log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/kernel/Cargo.toml b/kernel/Cargo.toml index 66a24ec..eefcc75 100644 --- a/kernel/Cargo.toml +++ b/kernel/Cargo.toml @@ -47,7 +47,7 @@ lazy_static = { version = "1.2", features = ["spin_no_std"] } smoltcp = { version = "0.5.0", default-features = false, features = ["alloc", "log", "proto-ipv4", "proto-igmp", "socket-icmp", "socket-udp", "socket-tcp"] } bit-allocator = { path = "../crate/bit-allocator" } rcore-memory = { path = "../crate/memory" } -rcore-process = { path = "../crate/process" } +rcore-thread = { path = "../crate/thread" } simple-filesystem = { git = "https://github.com/wangrunji0408/SimpleFileSystem-Rust" } [target.'cfg(target_arch = "x86_64")'.dependencies] diff --git a/kernel/src/lib.rs b/kernel/src/lib.rs index 53a0129..3ea683e 100644 --- a/kernel/src/lib.rs +++ b/kernel/src/lib.rs @@ -13,7 +13,7 @@ extern crate alloc; pub use crate::process::{processor, new_kernel_context}; -use rcore_process::thread; +use rcore_thread::std_thread as thread; use linked_list_allocator::LockedHeap; #[macro_use] // print! diff --git a/kernel/src/process/context.rs b/kernel/src/process/context.rs index 71f63d5..ac6dbca 100644 --- a/kernel/src/process/context.rs +++ b/kernel/src/process/context.rs @@ -3,7 +3,7 @@ use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec::V use log::*; use simple_filesystem::file::File; use spin::Mutex; -use rcore_process::Context; +use rcore_thread::Context; use xmas_elf::{ElfFile, header, program::{Flags, Type}}; use crate::arch::interrupt::{Context as ArchContext, TrapFrame}; diff --git a/kernel/src/process/mod.rs b/kernel/src/process/mod.rs index 2f59994..73cbb23 100644 --- a/kernel/src/process/mod.rs +++ b/kernel/src/process/mod.rs @@ -1,5 +1,5 @@ pub use self::context::Process; -pub use rcore_process::*; +pub use rcore_thread::*; use crate::consts::{MAX_CPU_NUM, MAX_PROCESS_NUM}; use crate::arch::cpu; use alloc::{boxed::Box, sync::Arc}; @@ -10,7 +10,7 @@ pub mod context; pub fn init() { // NOTE: max_time_slice <= 5 to ensure 'priority' test pass let scheduler = Box::new(scheduler::RRScheduler::new(5)); - let manager = Arc::new(ProcessManager::new(scheduler, MAX_PROCESS_NUM)); + let manager = Arc::new(ThreadPool::new(scheduler, MAX_PROCESS_NUM)); unsafe { for cpu_id in 0..MAX_CPU_NUM { diff --git a/kernel/src/shell.rs b/kernel/src/shell.rs index 4fa2057..bdfea25 100644 --- a/kernel/src/shell.rs +++ b/kernel/src/shell.rs @@ -3,6 +3,7 @@ use alloc::string::String; use crate::fs::{ROOT_INODE, INodeExt}; use crate::process::*; +use crate::thread; pub fn run_user_shell() { if let Ok(inode) = ROOT_INODE.lookup("sh") { diff --git a/kernel/src/trap.rs b/kernel/src/trap.rs index c5f1e08..61e2495 100644 --- a/kernel/src/trap.rs +++ b/kernel/src/trap.rs @@ -14,7 +14,7 @@ pub fn timer() { pub fn error(tf: &TrapFrame) -> ! { error!("{:#x?}", tf); - let pid = processor().pid(); + let pid = processor().tid(); error!("On CPU{} Process {}", cpu::id(), pid); processor().manager().exit(pid, 0x100);