diff --git a/src/include/kernel/sched.h b/src/include/kernel/sched.h index 1da42f2d..10aaa4b4 100644 --- a/src/include/kernel/sched.h +++ b/src/include/kernel/sched.h @@ -67,6 +67,7 @@ typedef struct _proc_t{ dirnode_t* cwd; event_t childevent; mode_t umask; + int threadexitlock; } proc_t; @@ -76,7 +77,7 @@ typedef struct{ int lock; } sched_queue; -void sched_dequeue(); +void sched_dequeue(long state); proc_t* sched_getinit(); thread_t* sched_newuthread(void* ip, size_t stacksize, void* stack, proc_t* proc, bool run, int prio); thread_t* sched_newkthread(void* ip, size_t stacksize, bool run, int prio); diff --git a/src/sys/sched/scheduler.c b/src/sys/sched/scheduler.c index f100897f..a89f1b25 100644 --- a/src/sys/sched/scheduler.c +++ b/src/sys/sched/scheduler.c @@ -363,7 +363,7 @@ void sched_eventsignal(event_t* event, thread_t* thread){ spinlock_release(&queues[thread->priority].lock); } -void sched_dequeue(){ +void sched_dequeue(long state){ timer_stop(); arch_interrupt_disable(); @@ -377,17 +377,18 @@ void sched_dequeue(){ arch_getcls()->thread = thread; vmm_switchcontext(thread->ctx); - + + thread->state = state; + if(state == THREAD_STATE_DEAD) + spinlock_release(&thread->proc->threadexitlock); + switch_thread(thread); } __attribute__((noreturn)) int sched_die(){ - - arch_getcls()->thread->state = THREAD_STATE_DEAD; - - sched_dequeue(); + sched_dequeue(THREAD_STATE_DEAD); } void sched_threadexitcheck(){ diff --git a/src/sys/syscalls/exit.c b/src/sys/syscalls/exit.c index e5ce9974..78487768 100644 --- a/src/sys/syscalls/exit.c +++ b/src/sys/syscalls/exit.c @@ -75,7 +75,7 @@ void syscall_exit(int status){ spinlock_release(&proc->lock); spinlock_release(&init->lock); - sched_dequeue(); + sched_die(); __builtin_unreachable();