Send event on thread death.

This commit is contained in:
4lDO2
2025-02-21 11:53:38 +01:00
parent db5931504d
commit f40ec48b3e
6 changed files with 55 additions and 15 deletions
+7 -2
View File
@@ -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<Frame>,
// TODO: id can reappear after wraparound?
pub owner_proc_id: Option<NonZeroUsize>,
// 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<Context> {
pub fn new(owner_proc_id: Option<NonZeroUsize>) -> Result<Context> {
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,
+11 -4
View File
@@ -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<BTreeSet<ContextRef>> = 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<Arc<RwSpinlock<Context>>> {
pub fn spawn(
userspace_allowed: bool,
owner_proc_id: Option<NonZeroUsize>,
func: extern "C" fn(),
) -> Result<Arc<RwSpinlock<Context>>> {
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()
+2 -1
View File
@@ -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();
+13 -1
View File
@@ -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)),
};
+1 -2
View File
@@ -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<usize> into -errno
+21 -5
View File
@@ -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!();