Add exit_thread(2).

This commit is contained in:
Jonas 'Sortie' Termansen 2013-08-31 19:35:17 +02:00
parent 202cf40881
commit 4ea6aa710c
6 changed files with 154 additions and 2 deletions

View File

@ -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 <http://www.gnu.org/licenses/>.
sortix/exit.h
Flags and constants related to process and thread exiting.
*******************************************************************************/
#ifndef INCLUDE_SORTIX_EXIT_H
#define INCLUDE_SORTIX_EXIT_H
#include <sys/cdefs.h>
#include <sys/__/types.h>
__BEGIN_DECLS
#ifndef __size_t_defined
#define __size_t_defined
#define __need_size_t
#include <stddef.h>
#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

View File

@ -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

View File

@ -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 <errno.h>
#include <string.h>
#include <sortix/exit.h>
#include <sortix/mman.h>
#include <sortix/signal.h>
#include <sortix/kernel/copy.h>
#include <sortix/kernel/interrupt.h>
#include <sortix/kernel/kernel.h>
#include <sortix/kernel/kthread.h>
@ -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);

View File

@ -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 \

View File

@ -36,6 +36,7 @@
#if defined(_SORTIX_SOURCE)
#include <stdarg.h>
#include <stdint.h>
#include <sortix/exit.h>
#include <sortix/fork.h>
__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);

View File

@ -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 <http://www.gnu.org/licenses/>.
unistd/exit_thread.cpp
Destroys the current thread immediately with no clean up.
*******************************************************************************/
#include <sys/syscall.h>
#include <unistd.h>
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);
}