diff --git a/kernel/include/sortix/exit.h b/kernel/include/sortix/exit.h
new file mode 100644
index 00000000..85ca5535
--- /dev/null
+++ b/kernel/include/sortix/exit.h
@@ -0,0 +1,55 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
+
+ This file is part of Sortix.
+
+ Sortix is free software: you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option) any later
+ version.
+
+ Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
+
+ sortix/exit.h
+ Flags and constants related to process and thread exiting.
+
+*******************************************************************************/
+
+#ifndef INCLUDE_SORTIX_EXIT_H
+#define INCLUDE_SORTIX_EXIT_H
+
+#include
+
+#include
+
+__BEGIN_DECLS
+
+#ifndef __size_t_defined
+#define __size_t_defined
+#define __need_size_t
+#include
+#endif
+
+struct exit_thread
+{
+ void* unmap_from;
+ size_t unmap_size;
+ void* zero_from;
+ size_t zero_size;
+ unsigned long reserved[4];
+};
+
+#define EXIT_THREAD_ONLY_IF_OTHERS (1<<0)
+#define EXIT_THREAD_UNMAP (1<<1)
+#define EXIT_THREAD_ZERO (1<<2)
+
+__END_DECLS
+
+#endif
diff --git a/kernel/include/sortix/syscallnum.h b/kernel/include/sortix/syscallnum.h
index c182a1cc..9fdcd86e 100644
--- a/kernel/include/sortix/syscallnum.h
+++ b/kernel/include/sortix/syscallnum.h
@@ -153,6 +153,7 @@
#define SYSCALL_RDMSR 129
#define SYSCALL_WRMSR 130
#define SYSCALL_SCHED_YIELD 131
-#define SYSCALL_MAX_NUM 132 /* index of highest constant + 1 */
+#define SYSCALL_EXIT_THREAD 132
+#define SYSCALL_MAX_NUM 133 /* index of highest constant + 1 */
#endif
diff --git a/kernel/thread.cpp b/kernel/thread.cpp
index a1abce0b..174cea62 100644
--- a/kernel/thread.cpp
+++ b/kernel/thread.cpp
@@ -1,6 +1,6 @@
/*******************************************************************************
- Copyright(C) Jonas 'Sortie' Termansen 2011, 2012.
+ Copyright(C) Jonas 'Sortie' Termansen 2011, 2012, 2014.
This file is part of Sortix.
@@ -26,9 +26,11 @@
#include
#include
+#include
#include
#include
+#include
#include
#include
#include
@@ -279,6 +281,61 @@ bool Thread::DeliverSignal(int signum)
return true;
}
+static int sys_exit_thread(int status,
+ int flags,
+ const struct exit_thread* user_extended)
+{
+ if ( flags & ~(EXIT_THREAD_ONLY_IF_OTHERS |
+ EXIT_THREAD_UNMAP |
+ EXIT_THREAD_ZERO) )
+ return errno = EINVAL, -1;
+
+ Thread* thread = CurrentThread();
+ Process* process = CurrentProcess();
+
+ struct exit_thread extended;
+ if ( !user_extended )
+ memset(&extended, 0, sizeof(extended));
+ else if ( !CopyFromUser(&extended, user_extended, sizeof(extended)) )
+ return -1;
+
+ extended.unmap_size = Page::AlignUp(extended.unmap_size);
+
+ kthread_mutex_lock(&thread->process->threadlock);
+ bool is_others = false;
+ for ( Thread* iter = thread->process->firstthread;
+ !is_others && iter;
+ iter = iter->nextsibling )
+ {
+ if ( iter == thread )
+ continue;
+ if ( iter->terminated )
+ continue;
+ is_others = true;
+ }
+ kthread_mutex_unlock(&thread->process->threadlock);
+
+ if ( (flags & EXIT_THREAD_ONLY_IF_OTHERS) && !is_others )
+ return errno = ESRCH, -1;
+
+ if ( flags & EXIT_THREAD_UNMAP &&
+ Page::IsAligned((uintptr_t) extended.unmap_from) &&
+ extended.unmap_size )
+ {
+ ScopedLock lock(&process->segment_lock);
+ Memory::UnmapMemory(process, (uintptr_t) extended.unmap_from,
+ extended.unmap_size);
+ }
+
+ if ( flags & EXIT_THREAD_ZERO )
+ ZeroUser(extended.zero_from, extended.zero_size);
+
+ if ( !is_others )
+ thread->process->Exit(status);
+
+ kthread_exit();
+}
+
static int sys_kill(pid_t pid, int signum)
{
// Protect the system idle process.
@@ -320,6 +377,7 @@ static int sys_register_signal_handler(sighandler_t sighandler)
void Thread::Init()
{
+ Syscall::Register(SYSCALL_EXIT_THREAD, (void*) sys_exit_thread);
Syscall::Register(SYSCALL_KILL, (void*) sys_kill);
Syscall::Register(SYSCALL_RAISE, (void*) sys_raise);
Syscall::Register(SYSCALL_REGISTER_SIGNAL_HANDLER, (void*) sys_register_signal_handler);
diff --git a/libc/Makefile b/libc/Makefile
index 323cb714..e9b4ac60 100644
--- a/libc/Makefile
+++ b/libc/Makefile
@@ -499,6 +499,7 @@ unistd/execv.o \
unistd/execvpe.o \
unistd/execvp.o \
unistd/_exit.o \
+unistd/exit_thread.o \
unistd/faccessat.o \
unistd/fchdirat.o \
unistd/fchdir.o \
diff --git a/libc/include/unistd.h b/libc/include/unistd.h
index ebe357dd..ad667b0e 100644
--- a/libc/include/unistd.h
+++ b/libc/include/unistd.h
@@ -36,6 +36,7 @@
#if defined(_SORTIX_SOURCE)
#include
#include
+#include
#include
__BEGIN_DECLS
#ifndef __time_t_defined
@@ -401,6 +402,7 @@ ssize_t write(int, const void*, size_t);
#if defined(_SORTIX_SOURCE)
int alarmns(const struct timespec* delay, struct timespec* odelay);
int execvpe(const char*, char* const [], char* const []);
+int exit_thread(int, int, const struct exit_thread*);
int memstat(size_t* memused, size_t* memtotal);
int mkpartition(int fd, off_t start, off_t length);
pid_t sfork(int flags);
diff --git a/libc/unistd/exit_thread.cpp b/libc/unistd/exit_thread.cpp
new file mode 100644
index 00000000..ea73936a
--- /dev/null
+++ b/libc/unistd/exit_thread.cpp
@@ -0,0 +1,35 @@
+/*******************************************************************************
+
+ Copyright(C) Jonas 'Sortie' Termansen 2013, 2014.
+
+ This file is part of Sortix.
+
+ Sortix is free software: you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation, either version 3 of the License, or (at your option) any later
+ version.
+
+ Sortix is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+ FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
+ details.
+
+ You should have received a copy of the GNU General Public License along with
+ Sortix. If not, see .
+
+ unistd/exit_thread.cpp
+ Destroys the current thread immediately with no clean up.
+
+*******************************************************************************/
+
+#include
+
+#include
+
+DEFN_SYSCALL3(int, sys_exit_thread, SYSCALL_EXIT_THREAD, int, int, const struct exit_thread*);
+
+extern "C"
+int exit_thread(int status, int flags, const struct exit_thread* extended)
+{
+ return sys_exit_thread(status, flags, extended);
+}