From d33ef16f87c2d4461e1176b7f03d34383963bb95 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 14 Apr 2024 13:21:54 -0300 Subject: [PATCH] scheduler: sched_stopotherthreads() --- kernel-src/include/kernel/scheduler.h | 1 + kernel-src/sys/scheduler.c | 21 +++++++++++++++++++++ kernel-src/sys/syscalls/execve.c | 4 +++- kernel-src/sys/syscalls/exit.c | 16 +--------------- 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/kernel-src/include/kernel/scheduler.h b/kernel-src/include/kernel/scheduler.h index 1639b0ea..1b23171e 100644 --- a/kernel-src/include/kernel/scheduler.h +++ b/kernel-src/include/kernel/scheduler.h @@ -80,6 +80,7 @@ typedef struct proc_t { extern proc_t *sched_initproc; void sched_init(); +void sched_stopotherthreads(); void sched_runinit(); __attribute__((noreturn)) void sched_threadexit(); void sched_queue(thread_t *thread); diff --git a/kernel-src/sys/scheduler.c b/kernel-src/sys/scheduler.c index 610bd49a..677e483b 100644 --- a/kernel-src/sys/scheduler.c +++ b/kernel-src/sys/scheduler.c @@ -253,6 +253,27 @@ __attribute__((noreturn)) void sched_threadexit() { sched_stopcurrentthread(); } +void sched_stopotherthreads() { + thread_t *thread = _cpu()->thread; + proc_t *proc = thread->proc; + 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(); + + proc->nomorethreads = false; +} + static void yield(context_t *context) { thread_t *thread = _cpu()->thread; diff --git a/kernel-src/sys/syscalls/execve.c b/kernel-src/sys/syscalls/execve.c index 158cf32b..89254516 100644 --- a/kernel-src/sys/syscalls/execve.c +++ b/kernel-src/sys/syscalls/execve.c @@ -115,7 +115,9 @@ syscallret_t syscall_execve(context_t *context, char *upath, char *uargv[], char ret.ret = 0; - // TODO kill other threads and close CLOEXEC fds + // close CLOEXEC fds + + sched_stopotherthreads(); error: free(path); diff --git a/kernel-src/sys/syscalls/exit.c b/kernel-src/sys/syscalls/exit.c index 0e1fff85..ab7d4d3c 100644 --- a/kernel-src/sys/syscalls/exit.c +++ b/kernel-src/sys/syscalls/exit.c @@ -11,21 +11,7 @@ __attribute__((noreturn)) void syscall_exit(context_t *context, int status) { __assert(proc != sched_initproc); __assert(spinlock_try(&proc->exiting)); // only one thread can exit at the same time - // 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(); + sched_stopotherthreads(); // close fds for (int fd = 0; fd < proc->fdcount; ++fd)