From f40ec48b3eff35d09555320f7a1f54c5babdcf95 Mon Sep 17 00:00:00 2001 From: 4lDO2 <4lDO2@protonmail.com> Date: Fri, 21 Feb 2025 11:53:38 +0100 Subject: [PATCH] Send event on thread death. --- src/context/context.rs | 9 +++++++-- src/context/mod.rs | 15 +++++++++++---- src/main.rs | 3 ++- src/scheme/proc.rs | 14 +++++++++++++- src/syscall/mod.rs | 3 +-- src/syscall/process.rs | 26 +++++++++++++++++++++----- 6 files changed, 55 insertions(+), 15 deletions(-) diff --git a/src/context/context.rs b/src/context/context.rs index 65fbaf3982..0ce5601a37 100644 --- a/src/context/context.rs +++ b/src/context/context.rs @@ -25,6 +25,7 @@ use crate::syscall::error::{Error, Result, EAGAIN, ESRCH}; use super::{ empty_cr3, + file::FileDescription, memory::{AddrSpaceWrapper, GrantFileRef}, }; @@ -120,6 +121,9 @@ pub struct Context { pub being_sigkilled: bool, pub fmap_ret: Option, + // TODO: id can reappear after wraparound? + pub owner_proc_id: Option, + // TODO: Temporary replacement for existing kernel logic, replace with capabilities! pub ens: SchemeNamespace, pub euid: u32, @@ -145,9 +149,9 @@ pub struct SignalState { } impl Context { - pub fn new() -> Result { + pub fn new(owner_proc_id: Option) -> Result { static DEBUG_ID: AtomicU32 = AtomicU32::new(1); - let this = Context { + let this = Self { debug_id: DEBUG_ID.fetch_add(1, Ordering::Relaxed), sig: None, status: Status::HardBlocked { @@ -172,6 +176,7 @@ impl Context { userspace: false, fmap_ret: None, being_sigkilled: false, + owner_proc_id, ens: 0.into(), euid: u32::MAX, diff --git a/src/context/mod.rs b/src/context/mod.rs index 61f4795584..7d67b4f08e 100644 --- a/src/context/mod.rs +++ b/src/context/mod.rs @@ -2,6 +2,8 @@ //! //! For resources on contexts, please consult [wikipedia](https://en.wikipedia.org/wiki/Context_switch) and [osdev](https://wiki.osdev.org/Context_Switching) +use core::num::NonZeroUsize; + use alloc::{borrow::Cow, collections::BTreeSet, sync::Arc}; use spin::{RwLock, RwLockReadGuard, RwLockWriteGuard}; @@ -68,7 +70,8 @@ pub use self::arch::empty_cr3; static CONTEXTS: RwLock> = RwLock::new(BTreeSet::new()); pub fn init() { - let mut context = Context::new().expect("failed to create kmain context"); + let owner = None; // kmain not owned by any fd + let mut context = Context::new(owner).expect("failed to create kmain context"); context.sched_affinity = LogicalCpuSet::empty(); context.sched_affinity.atomic_set(crate::cpu_id()); context.name = Cow::Borrowed("kmain"); @@ -140,11 +143,15 @@ impl PartialEq for ContextRef { impl Eq for ContextRef {} /// Spawn a context from a function. -pub fn spawn(userspace_allowed: bool, func: extern "C" fn()) -> Result>> { +pub fn spawn( + userspace_allowed: bool, + owner_proc_id: Option, + func: extern "C" fn(), +) -> Result>> { let stack = Kstack::new()?; - let context_lock = - Arc::try_new(RwSpinlock::new(Context::new()?)).map_err(|_| Error::new(ENOMEM))?; + let context_lock = Arc::try_new(RwSpinlock::new(Context::new(owner_proc_id)?)) + .map_err(|_| Error::new(ENOMEM))?; CONTEXTS .write() diff --git a/src/main.rs b/src/main.rs index e60f2e3e40..acb2a3579c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -204,7 +204,8 @@ fn kmain(cpu_count: u32, bootstrap: Bootstrap) -> ! { #[cfg(feature = "profiling")] profiling::ready_for_profiling(); - match context::spawn(true, userspace_init) { + let owner = None; // kmain not owned by any fd + match context::spawn(true, owner, userspace_init) { Ok(context_lock) => { { let mut context = context_lock.write(); diff --git a/src/scheme/proc.rs b/src/scheme/proc.rs index 9dc0ed6597..6ae144362c 100644 --- a/src/scheme/proc.rs +++ b/src/scheme/proc.rs @@ -266,7 +266,19 @@ impl ProcScheme { OpenTy::Auth => { extern "C" fn ret() {} let context = match operation_str.ok_or(Error::new(ENOENT))? { - "new-context" => context::spawn(true, ret)?, + "new-context" => { + let id = NonZeroUsize::new(NEXT_ID.fetch_add(1, Ordering::Relaxed)) + .ok_or(Error::new(EMFILE))?; + let context = context::spawn(true, Some(id), ret)?; + HANDLES.write().insert( + id.get(), + Handle { + context, + kind: ContextHandle::OpenViaDup, + }, + ); + return Ok((id.get(), InternalFlags::empty())); + } "cur-context" => context::current(), _ => return Err(Error::new(ENOENT)), }; diff --git a/src/syscall/mod.rs b/src/syscall/mod.rs index bdedd328e6..42e10f065b 100644 --- a/src/syscall/mod.rs +++ b/src/syscall/mod.rs @@ -227,8 +227,7 @@ pub fn syscall(a: usize, b: usize, c: usize, d: usize, e: usize, f: usize) -> us percpu.inside_syscall.set(false); if percpu.switch_internals.being_sigkilled.get() { - todo!() - //exit(SIGKILL); + exit_this_context(); } // errormux turns Result into -errno diff --git a/src/syscall/process.rs b/src/syscall/process.rs index 62e96ef4f6..f89ab10453 100644 --- a/src/syscall/process.rs +++ b/src/syscall/process.rs @@ -2,15 +2,20 @@ use alloc::{collections::VecDeque, sync::Arc, vec::Vec}; use core::{mem, num::NonZeroUsize, sync::atomic::Ordering}; use spinning_top::RwSpinlock; use syscall::{ - sig_bit, RtSigInfo, SenderInfo, SIGCHLD, SIGKILL, SIGSTOP, SIGTERM, SIGTSTP, SIGTTIN, SIGTTOU, + sig_bit, EventFlags, RtSigInfo, SenderInfo, SIGCHLD, SIGKILL, SIGSTOP, SIGTERM, SIGTSTP, + SIGTTIN, SIGTTOU, }; use rmm::Arch; use spin::RwLock; -use crate::context::{ - memory::{AddrSpace, Grant, PageSpan}, - Context, ContextRef, +use crate::{ + context::{ + memory::{AddrSpace, Grant, PageSpan}, + Context, ContextRef, + }, + event, + scheme::GlobalSchemes, }; use crate::{ @@ -47,7 +52,18 @@ pub fn exit_this_context() -> ! { } drop(addrspace_opt); // TODO: Should status == Status::HardBlocked be handled differently? - context_lock.write().status = context::Status::Dead; + let owner = { + let mut guard = context_lock.write(); + guard.status = context::Status::Dead; + guard.owner_proc_id + }; + if let Some(owner) = owner { + let _ = event::trigger( + GlobalSchemes::Proc.scheme_id(), + owner.get(), + EventFlags::EVENT_READ, + ); + } let _ = context::contexts_mut().remove(&ContextRef(context_lock)); context::switch(); unreachable!();