sched: handle thread death in a less hacky way

This commit is contained in:
Matheus
2022-11-21 20:12:47 -03:00
parent e550d94c91
commit 8d8b319319
3 changed files with 43 additions and 13 deletions
+1
View File
@@ -18,6 +18,7 @@
#define THREAD_STATE_BLOCKED 2
#define THREAD_STATE_BLOCKED_INTR 3
#define THREAD_STATE_DEAD 4
#define THREAD_STATE_DESTROYED 5
#define PROC_STATE_NORMAL 0
#define PROC_STATE_ZOMBIE 1
-5
View File
@@ -49,11 +49,6 @@ void syscall_exit(int status){
event_signal(&proc->parent->childevent, true);
// context and thread destruction will happen in the waitpid()
// the pointer to this thread will reside in proc->threads
proc->threads = arch_getcls()->thread;
arch_interrupt_disable();
spinlock_release(&proc->lock);
+42 -8
View File
@@ -8,6 +8,7 @@
#include <arch/cls.h>
#include <arch/spinlock.h>
#include <kernel/alloc.h>
#include <arch/interrupt.h>
#define UNSUPPORTED "astral: waitpid: Unsupported waitpid options!\n"
#define UNSUPPORTED_PG "astral: waitpid: Process group waits are not supported yet.\n"
@@ -96,15 +97,48 @@ syscallret syscall_waitpid(pid_t pid, int *status, int options){
if(status)
*status = child->status; // XXX safer way of doing this
// the pointer to the last remaining thread is is proc->threads
thread_t* thread = child->threads;
int threadc = proc->threadcount;
free(thread->regs);
free(thread->kernelstackbase);
vmm_destroy(thread->ctx);
free(thread);
// free all the threads
while(proc->threadcount){
for(int t = 0; t < threadc; ++t){
thread_t* thread = proc->threads[t];
// XXX possible race condition here?
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){
thread_t* thread = proc->threads[t];
if(thread->state != THREAD_STATE_DESTROYED)
_panic("Freeing non-destroyed thread", NULL);
free(thread);
}
free(child);
retv.ret = child->pid;