scheduler: handle userland thread exit

This commit is contained in:
Matheus
2024-04-14 14:00:11 -03:00
parent d33ef16f87
commit 2cb94c2c2e
5 changed files with 68 additions and 37 deletions
+59 -1
View File
@@ -229,6 +229,47 @@ __attribute__((noreturn)) void sched_stopcurrentthread() {
switchthread(next);
}
void sched_procexit() {
proc_t *proc = _cpu()->thread->proc;
// close fds
for (int fd = 0; fd < proc->fdcount; ++fd)
fd_close(fd);
// zombify the proc
spinlock_acquire(&proc->lock);
VOP_RELEASE(proc->root);
VOP_RELEASE(proc->cwd);
proc->state = SCHED_PROC_STATE_ZOMBIE;
proc_t *lastchild = proc->child;
spinlock_acquire(&sched_initproc->lock);
bool haszombie = false;
while (lastchild && lastchild->sibling) {
if (lastchild->state == SCHED_PROC_STATE_ZOMBIE)
haszombie = true;
lastchild->parent = sched_initproc;
lastchild = lastchild->sibling;
}
if (lastchild) {
lastchild->sibling = sched_initproc->child;
sched_initproc->child = proc->child;
}
spinlock_release(&sched_initproc->lock);
spinlock_release(&proc->lock);
semaphore_signal(&proc->parent->waitsem);
if (haszombie)
semaphore_signal(&sched_initproc->waitsem);
}
__attribute__((noreturn)) void sched_threadexit() {
thread_t *thread = _cpu()->thread;
proc_t *proc = thread->proc;
@@ -239,8 +280,13 @@ __attribute__((noreturn)) void sched_threadexit() {
if (proc) {
__atomic_fetch_sub(&proc->runningthreadcount, 1, __ATOMIC_SEQ_CST);
__assert(oldctx != &vmm_kernelctx);
if (proc->runningthreadcount == 0)
if (proc->runningthreadcount == 0) {
if (thread->shouldexit)
proc->status = -1;
sched_procexit();
vmm_destroycontext(oldctx);
}
}
interrupt_set(false);
@@ -253,6 +299,18 @@ __attribute__((noreturn)) void sched_threadexit() {
sched_stopcurrentthread();
}
// called right before going back to userspace in places like the syscall handler or arch_context_switch
__attribute__((no_caller_saved_registers)) void sched_userspacecheck(context_t *context) {
thread_t *thread = _cpu()->thread;
if (thread == NULL || ARCH_CONTEXT_ISUSER(context) == false)
return;
if (thread->shouldexit) {
interrupt_set(true);
sched_threadexit();
}
}
void sched_stopotherthreads() {
thread_t *thread = _cpu()->thread;
proc_t *proc = thread->proc;
-36
View File
@@ -13,43 +13,7 @@ __attribute__((noreturn)) void syscall_exit(context_t *context, int status) {
sched_stopotherthreads();
// close fds
for (int fd = 0; fd < proc->fdcount; ++fd)
fd_close(fd);
// zombify the proc
spinlock_acquire(&proc->lock);
VOP_RELEASE(proc->root);
VOP_RELEASE(proc->cwd);
proc->status = status;
proc->state = SCHED_PROC_STATE_ZOMBIE;
proc_t *lastchild = proc->child;
spinlock_acquire(&sched_initproc->lock);
bool haszombie = false;
while (lastchild && lastchild->sibling) {
if (lastchild->state == SCHED_PROC_STATE_ZOMBIE)
haszombie = true;
lastchild->parent = sched_initproc;
lastchild = lastchild->sibling;
}
if (lastchild) {
lastchild->sibling = sched_initproc->child;
sched_initproc->child = proc->child;
}
spinlock_release(&sched_initproc->lock);
spinlock_release(&proc->lock);
semaphore_signal(&proc->parent->waitsem);
if (haszombie)
semaphore_signal(&sched_initproc->waitsem);
sched_threadexit();
}