#include <lunaix/process.h>
#include <lunaix/sched.h>
#include <lunaix/signal.h>
+#include <lunaix/status.h>
#include <lunaix/syscall.h>
extern struct scheduler sched_ctx; /* kernel/sched.c */
// 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 =
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();
}
__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