diff --git a/Kernel/Process.cpp b/Kernel/Process.cpp index 64a5959a77..b18ea40ebd 100644 --- a/Kernel/Process.cpp +++ b/Kernel/Process.cpp @@ -2443,6 +2443,18 @@ int Process::sys$create_thread(int(*entry)(void*), void* argument) return 0; } +void Process::sys$exit_thread(int code) +{ + InterruptDisabler disabler; + if (¤t->process().main_thread() == current) { + sys$exit(code); + return; + } + current->set_state(Thread::State::Dying); + Scheduler::pick_next_and_switch_now(); + ASSERT_NOT_REACHED(); +} + int Process::sys$gettid() { return current->tid(); diff --git a/Kernel/Process.h b/Kernel/Process.h index 7f2f25f63b..60a788a51b 100644 --- a/Kernel/Process.h +++ b/Kernel/Process.h @@ -175,6 +175,7 @@ public: int sys$setsockopt(const Syscall::SC_setsockopt_params*); int sys$restore_signal_mask(dword mask); int sys$create_thread(int(*)(void*), void*); + void sys$exit_thread(int code); int sys$rename(const char* oldpath, const char* newpath); int sys$systrace(pid_t); diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index e393b7e0de..252773348f 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -118,6 +118,11 @@ static dword handle(RegisterDump& regs, dword function, dword arg1, dword arg2, current->process().sys$exit((int)arg1); ASSERT_NOT_REACHED(); return 0; + case Syscall::SC_exit_thread: + cli(); + current->process().sys$exit_thread((int)arg1); + ASSERT_NOT_REACHED(); + break; case Syscall::SC_chdir: return current->process().sys$chdir((const char*)arg1); case Syscall::SC_uname: diff --git a/Kernel/Syscall.h b/Kernel/Syscall.h index 39f1a43a55..6bd55ce560 100644 --- a/Kernel/Syscall.h +++ b/Kernel/Syscall.h @@ -100,6 +100,7 @@ __ENUMERATE_SYSCALL(shm_close) \ __ENUMERATE_SYSCALL(ftruncate) \ __ENUMERATE_SYSCALL(systrace) \ + __ENUMERATE_SYSCALL(exit_thread) \ namespace Syscall { diff --git a/LibC/unistd.cpp b/LibC/unistd.cpp index 41051bb53b..e551f479a6 100644 --- a/LibC/unistd.cpp +++ b/LibC/unistd.cpp @@ -451,6 +451,12 @@ int create_thread(int(*entry)(void*), void* argument) __RETURN_WITH_ERRNO(rc, rc, -1); } +int exit_thread(int code) +{ + int rc = syscall(SC_exit_thread, code); + __RETURN_WITH_ERRNO(rc, rc, -1); +} + int ftruncate(int fd, off_t length) { int rc = syscall(SC_ftruncate, fd, length); diff --git a/LibC/unistd.h b/LibC/unistd.h index e3d0d85ffb..172cbcd8a1 100644 --- a/LibC/unistd.h +++ b/LibC/unistd.h @@ -18,6 +18,7 @@ int systrace(pid_t); int gettid(); int donate(int tid); int create_thread(int(*)(void*), void*); +void exit_thread(int); int create_shared_buffer(pid_t peer_pid, int, void** buffer); void* get_shared_buffer(int shared_buffer_id); int release_shared_buffer(int shared_buffer_id);