mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
waitpid: remake the thread deallocation loop and fix a few stupid mistakes
This commit is contained in:
+10
-28
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user