From 76435ad9a1e92a2cfa050af25eeabe2452be2390 Mon Sep 17 00:00:00 2001 From: Matheus Date: Sun, 1 Jan 2023 10:30:15 -0300 Subject: [PATCH] waitpid: remake the thread deallocation loop and fix a few stupid mistakes --- src/sys/syscalls/waitpid.c | 44 +++++++++++--------------------------- 1 file changed, 13 insertions(+), 31 deletions(-) diff --git a/src/sys/syscalls/waitpid.c b/src/sys/syscalls/waitpid.c index 5081d0a6..8d3991a3 100644 --- a/src/sys/syscalls/waitpid.c +++ b/src/sys/syscalls/waitpid.c @@ -22,21 +22,19 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){ retv.errno = EFAULT; return retv; } - + if(options != 0){ console_write(UNSUPPORTED, strlen(UNSUPPORTED)); retv.errno = ENOSYS; return retv; } - if(pid < -1 || pid == 0){ console_write(UNSUPPORTED_PG, strlen(UNSUPPORTED_PG)); retv.errno = ENOSYS; return retv; } - proc_t* proc = arch_getcls()->thread->proc; bool loop = true; @@ -68,17 +66,17 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){ } spinlock_release(&proc->lock); + if(loop){ event_wait(&proc->childevent, true); loop = false; continue; } + else break; } - - if(!child){ spinlock_release(&proc->lock); @@ -94,7 +92,6 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){ else{ proc->child = child->sibling; } - if(status){ retv.errno = u_memcpy(status, &child->status, sizeof(*status)); @@ -103,40 +100,25 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){ } - int threadc = proc->threadcount; + int threadc = child->threadcount; // free all the threads - while(proc->threadcount){ + for(int t = 0; t < threadc; ++t){ - for(int t = 0; t < threadc; ++t){ - - thread_t* thread = proc->threads[t]; - - // XXX possible race condition here? + thread_t* thread = child->threads[t]; - if(thread->state != THREAD_STATE_DEAD) - continue; + free(thread->regs); + free(thread->kernelstackbase); + vmm_destroy(thread->ctx); - free(thread->regs); - free(thread->kernelstackbase); - vmm_destroy(thread->ctx); - - thread->state = THREAD_STATE_DESTROYED; - - } - - arch_interrupt_disable(); - - sched_yield(); - - arch_interrupt_enable(); + thread->state = THREAD_STATE_DESTROYED; } for(int t = 0; t < threadc; ++t){ - thread_t* thread = proc->threads[t]; + thread_t* thread = child->threads[t]; if(thread->state != THREAD_STATE_DESTROYED) _panic("Freeing non-destroyed thread", NULL); @@ -144,9 +126,9 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){ free(thread); } - + free(child); - + retv.ret = child->pid; retv.errno = 0; return retv;