mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
syscalls: syscall_threadexit
This commit is contained in:
@@ -46,7 +46,8 @@ extern syscall_linkat
|
|||||||
extern syscall_recvmsg
|
extern syscall_recvmsg
|
||||||
extern syscall_futex
|
extern syscall_futex
|
||||||
extern syscall_newthread
|
extern syscall_newthread
|
||||||
func_count equ 45
|
extern syscall_threadexit
|
||||||
|
func_count equ 46
|
||||||
|
|
||||||
|
|
||||||
func_table:
|
func_table:
|
||||||
@@ -95,6 +96,7 @@ func_table:
|
|||||||
dq syscall_recvmsg
|
dq syscall_recvmsg
|
||||||
dq syscall_futex
|
dq syscall_futex
|
||||||
dq syscall_newthread
|
dq syscall_newthread
|
||||||
|
dq syscall_threadexit
|
||||||
section .text
|
section .text
|
||||||
global asm_syscall_entry
|
global asm_syscall_entry
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,9 @@ static char* syscalls[] = {
|
|||||||
"syscall_fchmod",
|
"syscall_fchmod",
|
||||||
"syscall_linkat",
|
"syscall_linkat",
|
||||||
"syscall_recvmsg",
|
"syscall_recvmsg",
|
||||||
"syscall_futex"
|
"syscall_futex",
|
||||||
|
"syscall_newthread",
|
||||||
|
"syscall_threadexit"
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#include <kernel/syscalls.h>
|
||||||
|
#include <kernel/sched.h>
|
||||||
|
#include <arch/cls.h>
|
||||||
|
#include <arch/spinlock.h>
|
||||||
|
|
||||||
|
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();
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user