obkrnl/proc/
mod.rs

1pub use self::abi::*;
2pub use self::pid::*;
3pub use self::process::*;
4pub use self::thread::*;
5
6use crate::event::{Event, EventSet};
7use crate::lock::{MappedMutex, Mutex, MutexGuard};
8use crate::signal::Signal;
9use crate::subsystem::Subsystem;
10use alloc::sync::{Arc, Weak};
11use core::error::Error;
12use core::fmt::{Display, Formatter};
13use hashbrown::HashMap;
14use macros::bitflag;
15
16mod abi;
17mod cell;
18mod pid;
19mod process;
20mod thread;
21
22/// Manage all processes in the system.
23pub struct ProcMgr {
24    procs: Mutex<HashMap<Pid, Weak<Proc>>>, // allproc + pidhashtbl + zombproc
25    events: Arc<EventSet<ProcEvents>>,
26}
27
28impl ProcMgr {
29    pub fn new() -> Arc<Self> {
30        let events = Arc::default();
31
32        Arc::new(Self {
33            procs: Mutex::new(HashMap::new()),
34            events,
35        })
36    }
37
38    pub fn list(&self) -> MappedMutex<impl ExactSizeIterator<Item = &Weak<Proc>> + '_> {
39        MutexGuard::map(self.procs.lock(), |procs| procs.values())
40    }
41
42    /// We imply `RFSTOPPED` to make [`ProcMgr`] not depend on the scheduler.
43    ///
44    /// See `fork1` on the Orbis for a reference.
45    ///
46    /// # Reference offsets
47    /// | Version | Offset |
48    /// |---------|--------|
49    /// |PS4 11.00|0x14B830|
50    pub fn fork(&self, abi: Arc<dyn ProcAbi>, flags: Fork) -> Result<Arc<Proc>, ForkError> {
51        // TODO: Refactor this for readability.
52        if (u32::from(flags) & 0x60008f8b) != 0
53            || flags.has_all(Fork::CopyFd | Fork::ClearFd)
54            || flags.has_any(Fork::ParentSignal.mask()) && !flags.has_any(Fork::CustomSignal)
55        {
56            return Err(ForkError::InvalidFlags);
57        }
58
59        if !flags.has_any(Fork::CreateProcess) {
60            todo!()
61        }
62
63        // Create process.
64        Ok(Proc::new(abi, &self.events))
65    }
66}
67
68impl Subsystem for ProcMgr {}
69
70/// Events that related to a process.
71#[derive(Default)]
72pub struct ProcEvents {
73    pub process_init: Event<fn(&mut Proc)>,
74    pub process_ctor: Event<fn(&Weak<Proc>)>,
75}
76
77/// Flags to control behavior of [`ProcMgr::fork()`].
78#[bitflag(u32)]
79pub enum Fork {
80    /// Duplicate file descriptor table to the child instead of sharing it with the parent. Cannot
81    /// used together with [`Self::clear_fd()`].
82    ///
83    /// This has the same value as `RFFDG`.
84    CopyFd = 0x4,
85    /// Create a child process.
86    ///
87    /// This has the same value as `RFPROC`.
88    CreateProcess = 0x10,
89    /// Create an empty file descriptor table for the child. Cannot used together with
90    /// [`Self::copy_fd()`].
91    ///
92    /// This has the same value as `RFCFDG`.
93    ClearFd = 0x1000,
94    /// Enable [`Self::parent_signal()`].
95    ///
96    /// This has the same value as `RFTSIGZMB`.
97    CustomSignal = 0x80000,
98    /// Use this signal instead of `SIGCHLD` to notify the parent. Requires
99    /// [`Self::custom_signal()`] to be enabled.
100    ///
101    /// This has the same value produced by `RFTSIGNUM` macro.
102    ParentSignal(Signal) = 0xFF00000,
103}
104
105/// Represents an error when [`ProcMgr::fork()`] fails.
106#[derive(Debug)]
107pub enum ForkError {
108    InvalidFlags,
109}
110
111impl Error for ForkError {}
112
113impl Display for ForkError {
114    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
115        match self {
116            Self::InvalidFlags => f.write_str("invalid flags"),
117        }
118    }
119}