diff --git a/src/arch/x86_64/syscall.asm b/src/arch/x86_64/syscall.asm index e938c615..af32f928 100644 --- a/src/arch/x86_64/syscall.asm +++ b/src/arch/x86_64/syscall.asm @@ -46,7 +46,8 @@ extern syscall_linkat extern syscall_recvmsg extern syscall_futex extern syscall_newthread -func_count equ 45 +extern syscall_threadexit +func_count equ 46 func_table: @@ -95,6 +96,7 @@ func_table: dq syscall_recvmsg dq syscall_futex dq syscall_newthread + dq syscall_threadexit section .text global asm_syscall_entry diff --git a/src/arch/x86_64/syscalllog.c b/src/arch/x86_64/syscalllog.c index be1144c9..11eb6a1b 100644 --- a/src/arch/x86_64/syscalllog.c +++ b/src/arch/x86_64/syscalllog.c @@ -47,7 +47,9 @@ static char* syscalls[] = { "syscall_fchmod", "syscall_linkat", "syscall_recvmsg", - "syscall_futex" + "syscall_futex", + "syscall_newthread", + "syscall_threadexit" }; diff --git a/src/sys/syscalls/threadexit.c b/src/sys/syscalls/threadexit.c new file mode 100644 index 00000000..33e6ac17 --- /dev/null +++ b/src/sys/syscalls/threadexit.c @@ -0,0 +1,30 @@ +#include +#include +#include +#include + +void syscall_threadexit(){ + + thread_t* thread = arch_getcls()->thread; + + proc_t* proc = thread->proc; + + // this loop is required in order to prevent a race condition related to syscall_exit() + + spinlock_acquire(&proc->threadexitlock); + + bool onlythread = true; + + for(int i = 0; i < proc->threadcount; ++i){ + if(proc->threads[i]->state != THREAD_STATE_DEAD && proc->threads[i] != thread){ + onlythread = false; + break; + } + } + + if(onlythread) + syscall_exit(0); // if it is the only thread, use syscall_exit instead. + + sched_die(); + +}