diff --git a/src/arch/x86_64/postsyscall.c b/src/arch/x86_64/postsyscall.c new file mode 100644 index 00000000..feb0b2bb --- /dev/null +++ b/src/arch/x86_64/postsyscall.c @@ -0,0 +1,5 @@ +#include + +void postsyscall(){ + sched_threadexitcheck(); +} diff --git a/src/arch/x86_64/syscall.asm b/src/arch/x86_64/syscall.asm index c9fd1c03..5a5f1d84 100644 --- a/src/arch/x86_64/syscall.asm +++ b/src/arch/x86_64/syscall.asm @@ -175,22 +175,29 @@ asm_syscall_entry: call [func_table + rax * 8] - ; restore entry state - + push rax + push rdx + ; DEBUG STUFF - ;push rax - ;push rdx - ;mov rsi,rdx ;mov rdi,r15 ;extern syscalllogger ;call syscalllogger - ;pop rdx - ;pop rax - + extern postsyscall + call postsyscall + + ; DEBUG STUFF END + + pop rdx + pop rax + + + + + ; restore entry state mov r11, 0x43 ; user data mov es,r11 diff --git a/src/include/kernel/sched.h b/src/include/kernel/sched.h index 21829e07..eaf20b90 100644 --- a/src/include/kernel/sched.h +++ b/src/include/kernel/sched.h @@ -8,6 +8,7 @@ #include #include #include +#include #define THREAD_PRIORITY_INTERRUPT 0 #define THREAD_PRIORITY_KERNEL 1 @@ -44,6 +45,7 @@ typedef struct _thread_t{ int priority; int umemoperror; void (*umemopfailaddr)(); + bool shouldexit; } thread_t; typedef struct _proc_t{ @@ -82,4 +84,5 @@ void sched_runinit(); void sched_eventsignal(event_t* event, thread_t* thread); void sched_block(bool interruptible); void sched_yield(); +void sched_threadexitcheck(); #endif diff --git a/src/sys/sched/scheduler.c b/src/sys/sched/scheduler.c index c1cc299b..b0035694 100644 --- a/src/sys/sched/scheduler.c +++ b/src/sys/sched/scheduler.c @@ -380,6 +380,12 @@ __attribute__((noreturn)) int sched_die(){ sched_dequeue(); } +void sched_threadexitcheck(){ + if(arch_getcls()->thread->shouldexit) + sched_die(); +} + + void sched_block(bool interruptible){ thread_t* thread = arch_getcls()->thread; diff --git a/src/sys/syscalls/exit.c b/src/sys/syscalls/exit.c index 6efe8237..e5ce9974 100644 --- a/src/sys/syscalls/exit.c +++ b/src/sys/syscalls/exit.c @@ -7,17 +7,38 @@ #include void syscall_exit(int status){ - proc_t* proc = arch_getcls()->thread->proc; + + thread_t* thread = arch_getcls()->thread; + proc_t* proc = thread->proc; + proc_t* init = sched_getinit(); + + if(proc == init) + _panic("Init exit", NULL); spinlock_acquire(&init->lock); spinlock_acquire(&proc->lock); - // TODO make all other threads exit + while(1){ + bool ok = true; + for(uintmax_t i = 0; i < proc->threadcount; ++i){ + if(proc->threads[i] == thread) + continue; + if(thread->state != THREAD_STATE_DEAD) + ok = false; + proc->threads[i]->shouldexit = true; + } - free(proc->threads); + if(ok) + break; + + arch_interrupt_disable(); + sched_yield(); + arch_interrupt_enable(); + + } for(uintmax_t fd = 0; fd < proc->fdtable.fdcount; ++ fd) fd_free(&proc->fdtable, fd);