asterinas/kernel/aster-nix/src/process/process_table.rs

112 lines
3.2 KiB
Rust

// SPDX-License-Identifier: MPL-2.0
//! A global table stores the pid to process mapping.
//! This table can be used to get process with pid.
//! TODO: progress group, thread all need similar mapping
use alloc::collections::btree_map::Values;
use super::{Pgid, Pid, Process, ProcessGroup, Session, Sid};
use crate::{
events::{Events, Observer, Subject},
prelude::*,
};
static PROCESS_TABLE: Mutex<BTreeMap<Pid, Arc<Process>>> = Mutex::new(BTreeMap::new());
static PROCESS_GROUP_TABLE: Mutex<BTreeMap<Pgid, Arc<ProcessGroup>>> = Mutex::new(BTreeMap::new());
static PROCESS_TABLE_SUBJECT: Subject<PidEvent> = Subject::new();
static SESSION_TABLE: Mutex<BTreeMap<Sid, Arc<Session>>> = Mutex::new(BTreeMap::new());
// ************ Process *************
/// Gets a process with pid
pub fn get_process(pid: &Pid) -> Option<Arc<Process>> {
PROCESS_TABLE.lock().get(pid).cloned()
}
pub(super) fn process_table_mut() -> MutexGuard<'static, BTreeMap<Pid, Arc<Process>>> {
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(),
}
}
/// 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<Pid, Arc<Process>>>,
}
impl<'a> ProcessTable<'a> {
/// Returns an iterator over the processes in the table.
pub fn iter(&self) -> ProcessTableIter {
ProcessTableIter {
inner: self.inner.values(),
}
}
}
/// An iterator over the processes of the process table.
pub struct ProcessTableIter<'a> {
inner: Values<'a, Pid, Arc<Process>>,
}
impl<'a> Iterator for ProcessTableIter<'a> {
type Item = &'a Arc<Process>;
fn next(&mut self) -> Option<Self::Item> {
self.inner.next()
}
}
// ************ Process Group *************
/// Gets a process group with `pgid`
pub fn get_process_group(pgid: &Pgid) -> Option<Arc<ProcessGroup>> {
PROCESS_GROUP_TABLE.lock().get(pgid).cloned()
}
/// Returns whether process table contains process group with pgid
pub fn contain_process_group(pgid: &Pgid) -> bool {
PROCESS_GROUP_TABLE.lock().contains_key(pgid)
}
pub(super) fn group_table_mut() -> MutexGuard<'static, BTreeMap<Pgid, Arc<ProcessGroup>>> {
PROCESS_GROUP_TABLE.lock()
}
// ************ Session *************
/// Gets a session with `sid`.
pub fn get_session(sid: &Sid) -> Option<Arc<Session>> {
SESSION_TABLE.lock().get(sid).map(Arc::clone)
}
pub(super) fn session_table_mut() -> MutexGuard<'static, BTreeMap<Sid, Arc<Session>>> {
SESSION_TABLE.lock()
}
// ************ Observer *************
/// Registers an observer which watches `PidEvent`.
pub fn register_observer(observer: Weak<dyn Observer<PidEvent>>) {
PROCESS_TABLE_SUBJECT.register_observer(observer, ());
}
/// Unregisters an observer which watches `PidEvent`.
pub fn unregister_observer(observer: &Weak<dyn Observer<PidEvent>>) {
PROCESS_TABLE_SUBJECT.unregister_observer(observer);
}
#[derive(Copy, Clone)]
pub enum PidEvent {
Exit(Pid),
}
impl Events for PidEvent {}