sched: add POSIX signal support
We have added POSIX signals to KirkOS It is very much experimental Alongside, we have PCI support fully, and we have imported sbase coreutils, I'm not too sure if all of them work, likely not, but a good few should be okay. Signed-off-by: kaguya <kaguya3311@national.shitposting.agency>
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
.section .text
|
||||
.global __mlibc_thread_entry
|
||||
__mlibc_thread_entry:
|
||||
pop %rdi
|
||||
pop %rsi
|
||||
pop %rdx
|
||||
call __mlibc_thread_trampoline
|
||||
|
||||
.section .note.GNU-stack,"",%progbits
|
||||
@@ -0,0 +1,60 @@
|
||||
#include <sys/mman.h>
|
||||
#include <mlibc/debug.hpp>
|
||||
#include <errno.h>
|
||||
#include <mlibc/all-sysdeps.hpp>
|
||||
#include <bits/ensure.h>
|
||||
#include <mlibc/tcb.hpp>
|
||||
|
||||
|
||||
extern "C" void __mlibc_thread_trampoline(void *(*fn)(void *), Tcb *tcb, void *arg) {
|
||||
if (mlibc::sys_tcb_set(tcb)) {
|
||||
__ensure(!"failed to set tcb for new thread");
|
||||
}
|
||||
|
||||
while (__atomic_load_n(&tcb->tid, __ATOMIC_RELAXED) == 0) {
|
||||
mlibc::sys_futex_wait(&tcb->tid, 0, nullptr);
|
||||
}
|
||||
|
||||
tcb->invokeThreadFunc(reinterpret_cast<void *>(fn), arg);
|
||||
|
||||
__atomic_store_n(&tcb->didExit, 1, __ATOMIC_RELEASE);
|
||||
mlibc::sys_futex_wake(&tcb->didExit);
|
||||
|
||||
mlibc::sys_thread_exit();
|
||||
}
|
||||
|
||||
#define DEFAULT_STACK (2 * 1024 * 1024)
|
||||
|
||||
namespace mlibc {
|
||||
int sys_prepare_stack(void **stack, void *entry, void *arg, void *tcb, size_t *stack_size, size_t *guard_size, void **stack_base) {
|
||||
// TODO guard
|
||||
|
||||
mlibc::infoLogger() << "mlibc: sys_prepare_stack() does not setup a guard!" << frg::endlog;
|
||||
|
||||
*guard_size = 0;
|
||||
|
||||
*stack_size = *stack_size ? *stack_size : DEFAULT_STACK;
|
||||
|
||||
if (!*stack) {
|
||||
*stack_base = mmap(NULL, *stack_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
|
||||
if (*stack_base == MAP_FAILED) {
|
||||
return errno;
|
||||
}
|
||||
} else {
|
||||
*stack_base = *stack;
|
||||
}
|
||||
|
||||
*stack = (void *)((char *)*stack_base + *stack_size);
|
||||
|
||||
void **stack_it = (void **)*stack;
|
||||
|
||||
*--stack_it = arg;
|
||||
*--stack_it = tcb;
|
||||
*--stack_it = entry;
|
||||
|
||||
*stack = (void *)stack_it;
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,11 @@
|
||||
#define SYS_mmap 9
|
||||
#define SYS_mprotect 10
|
||||
#define SYS_munmap 11
|
||||
#define SYS_sigaction 13
|
||||
#define SYS_sigprocmask 14
|
||||
#define SYS_sigreturn 15
|
||||
#define SYS_ioctl 16
|
||||
#define SYS_pause 34
|
||||
#define SYS_nanosleep 35
|
||||
#define SYS_getpid 39
|
||||
#define SYS_fork 57
|
||||
@@ -22,9 +26,15 @@
|
||||
#define SYS_rmdir 84
|
||||
#define SYS_readdir 89
|
||||
#define SYS_puts 103
|
||||
#define SYS_setpgid 109
|
||||
#define SYS_getppid 110
|
||||
#define SYS_getpgrp 111
|
||||
#define SYS_setsid 112
|
||||
#define SYS_waitpid 114
|
||||
#define SYS_getpgid 121
|
||||
#define SYS_getsid 124
|
||||
#define SYS_sigpending 127
|
||||
#define SYS_sigsuspend 130
|
||||
#define SYS_prctl 157
|
||||
#define SYS_futex 202
|
||||
#define SYS_openat 257
|
||||
|
||||
@@ -98,5 +98,7 @@ libc_sources += files(
|
||||
'sysdeps.cpp',
|
||||
'syscall.cpp',
|
||||
'dso.c',
|
||||
'generic/thread.cpp',
|
||||
'generic/thread.S',
|
||||
)
|
||||
libc_include_dirs += include_directories('include')
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
__builtin_unreachable(); \
|
||||
})
|
||||
|
||||
extern "C" void __mlibc_sigreturn_trampoline(void);
|
||||
__asm__ (
|
||||
".global __mlibc_sigreturn_trampoline\n"
|
||||
"__mlibc_sigreturn_trampoline:\n"
|
||||
" mov $15, %rax\n" /* SYS_sigreturn */
|
||||
" syscall\n"
|
||||
" ud2\n" /* should never reach here */
|
||||
);
|
||||
|
||||
namespace mlibc {
|
||||
|
||||
|
||||
@@ -122,15 +131,6 @@ int sys_clone(void *tcb, pid_t *pid_out, void *stack) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void __mlibc_thread_entry() {
|
||||
/* Minimal stub so linking succeeds.
|
||||
If you need real pthread support later, replace this with the
|
||||
proper mlibc thread startup logic (pop start_routine + arg from stack,
|
||||
call it, then sys_thread_exit). */
|
||||
mlibc::sys_libc_panic();
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
int sys_tcgetattr(int fd, struct termios *attr) {
|
||||
int ret;
|
||||
if (int r = sys_ioctl(fd, TCGETS, attr, &ret) != 0) {
|
||||
@@ -345,15 +345,24 @@ gid_t sys_getgid() { return 0; }
|
||||
|
||||
int sys_setgid(gid_t) { return 0; }
|
||||
|
||||
int sys_getpgid(pid_t, pid_t *) { return 0; }
|
||||
int sys_getpgid(pid_t pid, pid_t *out) {
|
||||
int ret = (int)syscall(SYS_getpgid, pid);
|
||||
if (ret < 0) return -ret;
|
||||
*out = (pid_t)ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
gid_t sys_getegid() { return 0; }
|
||||
|
||||
int sys_setpgid(pid_t, pid_t) { return 0; }
|
||||
int sys_setpgid(pid_t pid, pid_t pgid) {
|
||||
int ret = (int)syscall(SYS_setpgid, pid, pgid);
|
||||
if (ret < 0) return -ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_kill(pid_t p, int sig) {
|
||||
(void)sig;
|
||||
syscall(SYS_kill, p);
|
||||
int ret = (int)syscall(SYS_kill, p, sig);
|
||||
if (ret < 0) return -ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -479,23 +488,79 @@ int sys_rmdir(const char *path) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sys_setsid(pid_t *sid) {
|
||||
(void)sid;
|
||||
int ret = syscall(SYS_setsid);
|
||||
ret = ret < 0 ? -ret : ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sys_sigprocmask(int, const sigset_t *__restrict, sigset_t *__restrict) {
|
||||
mlibc::infoLogger() << "mlibc: sys_sigprocmask() is a stub\n" << frg::endlog;
|
||||
int sys_setsid(pid_t *out) {
|
||||
int ret = (int)syscall(SYS_setsid);
|
||||
if (ret < 0) return -ret;
|
||||
*out = (pid_t)ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_sigaction(int, const struct sigaction *, struct sigaction *) {
|
||||
mlibc::infoLogger() << "mlibc: sys_sigaction() is a stub\n" << frg::endlog;
|
||||
int sys_sigprocmask(int how, const sigset_t *__restrict set, sigset_t *__restrict oldset) {
|
||||
int ret = (int)syscall(SYS_sigprocmask, how, set, oldset);
|
||||
if (ret < 0) return -ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_sigaction(int how, const struct sigaction *act, struct sigaction *oldact) {
|
||||
struct sigaction kact;
|
||||
const struct sigaction *act_to_pass = act;
|
||||
if (act) {
|
||||
kact = *act;
|
||||
/* Always set SA_RESTORER + sa_restorer; the kernel requires this
|
||||
* to know where to return after the handler. If userspace already
|
||||
* provided one (e.g. for sigaltstack tricks), honor it. */
|
||||
if (!(kact.sa_flags & SA_RESTORER) || kact.sa_restorer == nullptr) {
|
||||
kact.sa_flags |= SA_RESTORER;
|
||||
kact.sa_restorer = __mlibc_sigreturn_trampoline;
|
||||
}
|
||||
act_to_pass = &kact;
|
||||
}
|
||||
int ret = (int)syscall(SYS_sigaction, how, act_to_pass, oldact);
|
||||
if (ret < 0) return -ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_pause(void) {
|
||||
int ret = (int)syscall(SYS_pause);
|
||||
/* pause always returns -EINTR per POSIX */
|
||||
if (ret < 0) return -ret;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sys_sigsuspend(const sigset_t *mask) {
|
||||
int ret = (int)syscall(SYS_sigsuspend, mask);
|
||||
if (ret < 0) return -ret;
|
||||
return -1; /* never returns success */
|
||||
}
|
||||
|
||||
int sys_sigpending(sigset_t *set) {
|
||||
int ret = (int)syscall(SYS_sigpending, set);
|
||||
if (ret < 0) return -ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_getsid(pid_t pid, pid_t *out) {
|
||||
int ret = (int)syscall(SYS_getsid, pid);
|
||||
if (ret < 0) return -ret;
|
||||
*out = (pid_t)ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_tcgetpgrp(int fd, pid_t *out) {
|
||||
int pgrp;
|
||||
int ret_val;
|
||||
if (int r = sys_ioctl(fd, TIOCGPGRP, &pgrp, &ret_val); r != 0)
|
||||
return r;
|
||||
*out = (pid_t)pgrp;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sys_tcsetpgrp(int fd, pid_t pgrp) {
|
||||
int ret_val;
|
||||
int pg = (int)pgrp;
|
||||
return sys_ioctl(fd, TIOCSPGRP, &pg, &ret_val);
|
||||
}
|
||||
|
||||
int sys_waitpid(pid_t pid, int *status, int flags, struct rusage *ru, pid_t *ret_pid) {
|
||||
if (ru) {
|
||||
mlibc::infoLogger() << "mlibc: struct rusage in sys_waitpid is unsupported\n"
|
||||
|
||||
Reference in New Issue
Block a user