From d3b17b90b90cb0aa9b95d037710f07a484357842 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 14 Apr 2024 13:12:28 -0300 Subject: [PATCH] exit syscall: stop other threads --- kernel-src/include/kernel/scheduler.h | 2 ++ kernel-src/sys/syscalls/exit.c | 19 ++++++++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/kernel-src/include/kernel/scheduler.h b/kernel-src/include/kernel/scheduler.h index 98cf9173..1639b0ea 100644 --- a/kernel-src/include/kernel/scheduler.h +++ b/kernel-src/include/kernel/scheduler.h @@ -69,6 +69,8 @@ typedef struct proc_t { vnode_t *root; spinlock_t nodeslock; semaphore_t waitsem; + spinlock_t exiting; + bool nomorethreads; } proc_t; #include diff --git a/kernel-src/sys/syscalls/exit.c b/kernel-src/sys/syscalls/exit.c index 749c5981..0e1fff85 100644 --- a/kernel-src/sys/syscalls/exit.c +++ b/kernel-src/sys/syscalls/exit.c @@ -9,12 +9,29 @@ __attribute__((noreturn)) void syscall_exit(context_t *context, int status) { thread_t *thread = _cpu()->thread; proc_t *proc = thread->proc; __assert(proc != sched_initproc); + __assert(spinlock_try(&proc->exiting)); // only one thread can exit at the same time - // TODO stop other threads + // stop other threads + spinlock_acquire(&proc->lock); + proc->nomorethreads = true; + for (int i = 0; i < proc->threadtablesize; ++i) { + if (proc->threads[i] == NULL || proc->threads[i] == thread) + continue; + + proc->threads[i]->shouldexit = true; + sched_wakeup(proc->threads[i], SCHED_WAKEUP_REASON_INTERRUPTED); + } + + spinlock_release(&proc->lock); + + while (__atomic_load_n(&proc->runningthreadcount, __ATOMIC_SEQ_CST) > 1) sched_yield(); + + // close fds for (int fd = 0; fd < proc->fdcount; ++fd) fd_close(fd); + // zombify the proc spinlock_acquire(&proc->lock); VOP_RELEASE(proc->root);