Add exit_thread(2).
This commit is contained in:
parent
202cf40881
commit
4ea6aa710c
|
@ -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
|
|
@ -153,6 +153,7 @@
|
||||||
#define SYSCALL_RDMSR 129
|
#define SYSCALL_RDMSR 129
|
||||||
#define SYSCALL_WRMSR 130
|
#define SYSCALL_WRMSR 130
|
||||||
#define SYSCALL_SCHED_YIELD 131
|
#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
|
#endif
|
||||||
|
|
|
@ -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.
|
This file is part of Sortix.
|
||||||
|
|
||||||
|
@ -26,9 +26,11 @@
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <sortix/exit.h>
|
||||||
#include <sortix/mman.h>
|
#include <sortix/mman.h>
|
||||||
#include <sortix/signal.h>
|
#include <sortix/signal.h>
|
||||||
|
|
||||||
|
#include <sortix/kernel/copy.h>
|
||||||
#include <sortix/kernel/interrupt.h>
|
#include <sortix/kernel/interrupt.h>
|
||||||
#include <sortix/kernel/kernel.h>
|
#include <sortix/kernel/kernel.h>
|
||||||
#include <sortix/kernel/kthread.h>
|
#include <sortix/kernel/kthread.h>
|
||||||
|
@ -279,6 +281,61 @@ bool Thread::DeliverSignal(int signum)
|
||||||
return true;
|
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)
|
static int sys_kill(pid_t pid, int signum)
|
||||||
{
|
{
|
||||||
// Protect the system idle process.
|
// Protect the system idle process.
|
||||||
|
@ -320,6 +377,7 @@ static int sys_register_signal_handler(sighandler_t sighandler)
|
||||||
|
|
||||||
void Thread::Init()
|
void Thread::Init()
|
||||||
{
|
{
|
||||||
|
Syscall::Register(SYSCALL_EXIT_THREAD, (void*) sys_exit_thread);
|
||||||
Syscall::Register(SYSCALL_KILL, (void*) sys_kill);
|
Syscall::Register(SYSCALL_KILL, (void*) sys_kill);
|
||||||
Syscall::Register(SYSCALL_RAISE, (void*) sys_raise);
|
Syscall::Register(SYSCALL_RAISE, (void*) sys_raise);
|
||||||
Syscall::Register(SYSCALL_REGISTER_SIGNAL_HANDLER, (void*) sys_register_signal_handler);
|
Syscall::Register(SYSCALL_REGISTER_SIGNAL_HANDLER, (void*) sys_register_signal_handler);
|
||||||
|
|
|
@ -499,6 +499,7 @@ unistd/execv.o \
|
||||||
unistd/execvpe.o \
|
unistd/execvpe.o \
|
||||||
unistd/execvp.o \
|
unistd/execvp.o \
|
||||||
unistd/_exit.o \
|
unistd/_exit.o \
|
||||||
|
unistd/exit_thread.o \
|
||||||
unistd/faccessat.o \
|
unistd/faccessat.o \
|
||||||
unistd/fchdirat.o \
|
unistd/fchdirat.o \
|
||||||
unistd/fchdir.o \
|
unistd/fchdir.o \
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#if defined(_SORTIX_SOURCE)
|
#if defined(_SORTIX_SOURCE)
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <sortix/exit.h>
|
||||||
#include <sortix/fork.h>
|
#include <sortix/fork.h>
|
||||||
__BEGIN_DECLS
|
__BEGIN_DECLS
|
||||||
#ifndef __time_t_defined
|
#ifndef __time_t_defined
|
||||||
|
@ -401,6 +402,7 @@ ssize_t write(int, const void*, size_t);
|
||||||
#if defined(_SORTIX_SOURCE)
|
#if defined(_SORTIX_SOURCE)
|
||||||
int alarmns(const struct timespec* delay, struct timespec* odelay);
|
int alarmns(const struct timespec* delay, struct timespec* odelay);
|
||||||
int execvpe(const char*, char* const [], char* const []);
|
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 memstat(size_t* memused, size_t* memtotal);
|
||||||
int mkpartition(int fd, off_t start, off_t length);
|
int mkpartition(int fd, off_t start, off_t length);
|
||||||
pid_t sfork(int flags);
|
pid_t sfork(int flags);
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
Loading…
Reference in New Issue