diff --git a/kernel/src/fs/procfs/mod.rs b/kernel/src/fs/procfs/mod.rs index c60247c3..62fc5f55 100644 --- a/kernel/src/fs/procfs/mod.rs +++ b/kernel/src/fs/procfs/mod.rs @@ -130,7 +130,7 @@ impl DirOps for RootDirOps { cached_children .put_entry_if_not_found("meminfo", || MemInfoFileOps::new_inode(this_ptr.clone())); - for process in process_table::process_table().iter() { + for process in process_table::process_table_mut().iter() { let pid = process.pid().to_string(); cached_children.put_entry_if_not_found(&pid, || { PidDirOps::new_inode(process.clone(), this_ptr.clone()) diff --git a/kernel/src/process/kill.rs b/kernel/src/process/kill.rs index 658d774a..d6bd2316 100644 --- a/kernel/src/process/kill.rs +++ b/kernel/src/process/kill.rs @@ -105,7 +105,7 @@ pub fn tgkill(tid: Tid, tgid: Pid, signal: Option, ctx: &Context) -> /// if it is authorized to send the signal to the target group. pub fn kill_all(signal: Option, ctx: &Context) -> Result<()> { let current = current!(); - for process in process_table::process_table().iter() { + for process in process_table::process_table_mut().iter() { if Arc::ptr_eq(¤t, process) || process.is_init_process() { continue; } diff --git a/kernel/src/process/process_table.rs b/kernel/src/process/process_table.rs index 43507a9d..526703ff 100644 --- a/kernel/src/process/process_table.rs +++ b/kernel/src/process/process_table.rs @@ -14,43 +14,63 @@ use crate::{ prelude::*, }; -static PROCESS_TABLE: Mutex>> = Mutex::new(BTreeMap::new()); +static PROCESS_TABLE: Mutex = Mutex::new(ProcessTable::new()); static PROCESS_GROUP_TABLE: Mutex>> = Mutex::new(BTreeMap::new()); -static PROCESS_TABLE_SUBJECT: Subject = Subject::new(); static SESSION_TABLE: Mutex>> = Mutex::new(BTreeMap::new()); // ************ Process ************* - /// Gets a process with pid pub fn get_process(pid: Pid) -> Option> { - PROCESS_TABLE.lock().get(&pid).cloned() + PROCESS_TABLE.lock().get(pid).cloned() } -pub(super) fn process_table_mut() -> MutexGuard<'static, BTreeMap>> { +pub fn process_table_mut() -> MutexGuard<'static, ProcessTable> { PROCESS_TABLE.lock() } -/// Acquires a lock on the process table and returns a `ProcessTable`. -pub fn process_table() -> ProcessTable<'static> { - ProcessTable { - inner: PROCESS_TABLE.lock(), +/// Process Table. +pub struct ProcessTable { + inner: BTreeMap>, + subject: Subject, +} + +impl ProcessTable { + pub const fn new() -> Self { + Self { + inner: BTreeMap::new(), + subject: Subject::new(), + } } -} -/// A wrapper for the mutex-protected process table. -/// -/// It provides the `iter` method to iterator over the processes in the table. -pub struct ProcessTable<'a> { - inner: MutexGuard<'a, BTreeMap>>, -} + pub fn get(&self, pid: Pid) -> Option<&Arc> { + self.inner.get(&pid) + } + + pub fn insert(&mut self, pid: Pid, process: Arc) { + self.inner.insert(pid, process); + } + + pub fn remove(&mut self, pid: Pid) { + self.inner.remove(&pid); + self.subject.notify_observers(&PidEvent::Exit(pid)); + } -impl ProcessTable<'_> { /// Returns an iterator over the processes in the table. pub fn iter(&self) -> ProcessTableIter { ProcessTableIter { inner: self.inner.values(), } } + + /// Registers an observer which watches `PidEvent`. + pub fn register_observer(&self, observer: Weak>) { + self.subject.register_observer(observer, ()); + } + + /// Unregisters an observer which watches `PidEvent`. + pub fn unregister_observer(&self, observer: &Weak>) { + self.subject.unregister_observer(observer); + } } /// An iterator over the processes of the process table. @@ -97,12 +117,12 @@ pub(super) fn session_table_mut() -> MutexGuard<'static, BTreeMap>) { - PROCESS_TABLE_SUBJECT.register_observer(observer, ()); + PROCESS_TABLE.lock().register_observer(observer); } /// Unregisters an observer which watches `PidEvent`. pub fn unregister_observer(observer: &Weak>) { - PROCESS_TABLE_SUBJECT.unregister_observer(observer); + PROCESS_TABLE.lock().unregister_observer(observer); } #[derive(Copy, Clone)] diff --git a/kernel/src/process/wait.rs b/kernel/src/process/wait.rs index 3dfe35d7..4e8b6a8a 100644 --- a/kernel/src/process/wait.rs +++ b/kernel/src/process/wait.rs @@ -118,6 +118,6 @@ fn reap_zombie_child(process: &Process, pid: Pid) -> ExitCode { } } - process_table_mut.remove(&child_process.pid()); + process_table_mut.remove(child_process.pid()); child_process.exit_code() } diff --git a/kernel/src/syscall/set_get_priority.rs b/kernel/src/syscall/set_get_priority.rs index 3977e303..f215814f 100644 --- a/kernel/src/syscall/set_get_priority.rs +++ b/kernel/src/syscall/set_get_priority.rs @@ -69,7 +69,7 @@ fn get_processes(prio_target: PriorityTarget) -> Result>> { } PriorityTarget::User(uid) => { // Get the processes that are running under the specified user - let processes: Vec> = process_table::process_table() + let processes: Vec> = process_table::process_table_mut() .iter() .filter(|process| { let Some(main_thread) = process.main_thread() else {