mirror of
https://gitlab.com/sortix/sortix.git
synced 2023-02-13 20:55:38 -05:00
Add exit_thread(2).
This commit is contained in:
parent
202cf40881
commit
4ea6aa710c
6 changed files with 154 additions and 2 deletions
55
kernel/include/sortix/exit.h
Normal file
55
kernel/include/sortix/exit.h
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
|
|
35
libc/unistd/exit_thread.cpp
Normal file
35
libc/unistd/exit_thread.cpp
Normal 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);
|
||||
}
|
Loading…
Add table
Reference in a new issue