X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/509574b18a3373030cd0d7b979499499ff06dd9b..474a5dd282586c31abfefc7953f148acdc226731:/lunaix-os/kernel/signal.c diff --git a/lunaix-os/kernel/signal.c b/lunaix-os/kernel/signal.c index 3edb2f4..80a7098 100644 --- a/lunaix-os/kernel/signal.c +++ b/lunaix-os/kernel/signal.c @@ -1,6 +1,7 @@ #include #include #include +#include #include extern struct scheduler sched_ctx; /* kernel/sched.c */ @@ -9,35 +10,36 @@ void* default_handlers[_SIG_NUM] = { // TODO: 添加默认handler }; -void +// Referenced in kernel/asm/x86/interrupt.S +void* signal_dispatch() { // if (!(SEL_RPL(__current->intr_ctx.cs))) { // // 同特权级间调度不进行信号处理 - // return; + // return 0; // } if (!__current->sig_pending) { // 没有待处理信号 - return; + return 0; } int sig_selected = 31 - __builtin_clz(__current->sig_pending & ~__current->sig_mask); - __current->sig_pending = __current->sig_pending & ~(1 << sig_selected); + __current->sig_pending = __current->sig_pending & ~__SIGNAL(sig_selected); if (!__current->sig_handler[sig_selected] && !default_handlers[sig_selected]) { // 如果该信号没有handler,则忽略 - return; + return 0; } - uintptr_t ustack = __current->ustack_top; + uintptr_t ustack = __current->ustack_top & ~0xf; if ((int)(ustack - USTACK_END) < (int)sizeof(struct proc_sig)) { // 用户栈没有空间存放信号上下文 - return; + return 0; } struct proc_sig* sig_ctx = @@ -52,13 +54,16 @@ signal_dispatch() sig_ctx->signal_handler = default_handlers[sig_selected]; } - asm volatile("pushl %0\n" - "jmp handle_signal" ::"r"(sig_ctx)); + __current->sig_mask |= __SIGNAL(sig_selected); + + return sig_ctx; } __DEFINE_LXSYSCALL1(int, sigreturn, struct proc_sig, *sig_ctx) { __current->intr_ctx = sig_ctx->prev_context; + __current->sig_mask &= ~__SIGNAL(sig_ctx->sig_num); + __current->flags &= ~PROC_FINPAUSE; schedule(); } @@ -98,4 +103,17 @@ __DEFINE_LXSYSCALL2(int, signal, int, signum, sighandler_t, handler) __current->sig_handler[signum] = (void*)handler; return 0; +} + +__DEFINE_LXSYSCALL(int, pause) +{ + __current->flags |= PROC_FINPAUSE; + + __SYSCALL_INTERRUPTIBLE({ + while ((__current->flags & PROC_FINPAUSE)) { + sched_yield(); + } + }) + __current->k_status = EINTR; + return -1; } \ No newline at end of file