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