waitpid: remake the thread deallocation loop and fix a few stupid mistakes

This commit is contained in:
Matheus
2023-01-01 10:30:15 -03:00
parent 814ee1f69a
commit 76435ad9a1
+10 -28
View File
@@ -29,14 +29,12 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){
return retv; return retv;
} }
if(pid < -1 || pid == 0){ if(pid < -1 || pid == 0){
console_write(UNSUPPORTED_PG, strlen(UNSUPPORTED_PG)); console_write(UNSUPPORTED_PG, strlen(UNSUPPORTED_PG));
retv.errno = ENOSYS; retv.errno = ENOSYS;
return retv; return retv;
} }
proc_t* proc = arch_getcls()->thread->proc; proc_t* proc = arch_getcls()->thread->proc;
bool loop = true; bool loop = true;
@@ -69,17 +67,17 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){
spinlock_release(&proc->lock); spinlock_release(&proc->lock);
if(loop){ if(loop){
event_wait(&proc->childevent, true); event_wait(&proc->childevent, true);
loop = false; loop = false;
continue; continue;
} }
else break; else break;
} }
if(!child){ if(!child){
spinlock_release(&proc->lock); spinlock_release(&proc->lock);
retv.errno = ECHILD; retv.errno = ECHILD;
@@ -95,7 +93,6 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){
proc->child = child->sibling; proc->child = child->sibling;
} }
if(status){ if(status){
retv.errno = u_memcpy(status, &child->status, sizeof(*status)); retv.errno = u_memcpy(status, &child->status, sizeof(*status));
if(retv.errno) if(retv.errno)
@@ -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 // free all the threads
while(proc->threadcount){ for(int t = 0; t < threadc; ++t){
for(int t = 0; t < threadc; ++t){ thread_t* thread = child->threads[t];
thread_t* thread = proc->threads[t]; free(thread->regs);
free(thread->kernelstackbase);
vmm_destroy(thread->ctx);
// XXX possible race condition here? thread->state = THREAD_STATE_DESTROYED;
if(thread->state != THREAD_STATE_DEAD)
continue;
free(thread->regs);
free(thread->kernelstackbase);
vmm_destroy(thread->ctx);
thread->state = THREAD_STATE_DESTROYED;
}
arch_interrupt_disable();
sched_yield();
arch_interrupt_enable();
} }
for(int t = 0; t < threadc; ++t){ 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) if(thread->state != THREAD_STATE_DESTROYED)
_panic("Freeing non-destroyed thread", NULL); _panic("Freeing non-destroyed thread", NULL);