diff -ruN kozos29/kozos.h kozos30/kozos.h --- kozos29/kozos.h Mon Dec 17 21:53:06 2007 +++ kozos30/kozos.h Mon Dec 17 22:12:16 2007 @@ -4,6 +4,7 @@ #include "configure.h" typedef int (*kz_func)(int argc, char *argv[]); +typedef void (*kz_handler)(int signo); /* syscall */ int kz_run(kz_func func, char *name, int pri, int argc, char *argv[]); @@ -17,6 +18,7 @@ int kz_recv(int *idp, char **pp); int kz_timer(int msec); int kz_pending(); +int kz_sethandler(int signo, kz_handler handler); int kz_setsig(int signo); int kz_debug(int sockt); void *kz_kmalloc(int size); diff -ruN kozos29/syscall.c kozos30/syscall.c --- kozos29/syscall.c Mon Dec 17 21:53:06 2007 +++ kozos30/syscall.c Mon Dec 17 22:11:57 2007 @@ -112,6 +112,15 @@ return param.un.setsig.ret; } +int kz_sethandler(int signo, kz_handler handler) +{ + kz_syscall_param_t param; + param.un.sethandler.signo = signo; + param.un.sethandler.handler = handler; + kz_syscall(KZ_SYSCALL_TYPE_SETHANDLER, ¶m); + return param.un.sethandler.ret; +} + int kz_debug(int sockt) { kz_syscall_param_t param; diff -ruN kozos29/syscall.h kozos30/syscall.h --- kozos29/syscall.h Mon Dec 17 21:53:06 2007 +++ kozos30/syscall.h Mon Dec 17 22:11:23 2007 @@ -16,6 +16,7 @@ KZ_SYSCALL_TYPE_TIMER, KZ_SYSCALL_TYPE_PENDING, KZ_SYSCALL_TYPE_SETSIG, + KZ_SYSCALL_TYPE_SETHANDLER, KZ_SYSCALL_TYPE_DEBUG, KZ_SYSCALL_TYPE_KMALLOC, KZ_SYSCALL_TYPE_KMFREE, @@ -75,6 +76,11 @@ int signo; int ret; } setsig; + struct { + int signo; + kz_handler handler; + int ret; + } sethandler; struct { int sockt; int ret; diff -ruN kozos29/thread.c kozos30/thread.c --- kozos29/thread.c Mon Dec 17 21:53:06 2007 +++ kozos30/thread.c Mon Dec 17 22:23:51 2007 @@ -28,9 +28,10 @@ static unsigned int readyque_bitmap; static kz_timebuf *timers; static kz_thread *sigcalls[SIG_NUM]; +static kz_handler handlers[SIG_NUM]; static int debug_sockt = 0; sigset_t block; -static int on_os_stack = 0; +static stack_t intrstack; kz_thread *current; @@ -315,8 +316,17 @@ return 0; } +static int thread_sethandler(int signo, kz_handler handler) +{ + handlers[signo] = handler; + putcurrent(); + return 0; +} + static void extintr_proc(int signo) { + if (handlers[signo]) + handlers[signo](signo); if (sigcalls[signo]) sendmsg(sigcalls[signo], 0, 0, NULL); } @@ -401,6 +411,10 @@ case KZ_SYSCALL_TYPE_SETSIG: p->un.setsig.ret = thread_setsig(p->un.setsig.signo); break; + case KZ_SYSCALL_TYPE_SETHANDLER: + p->un.sethandler.ret = thread_sethandler(p->un.sethandler.signo, + p->un.sethandler.handler); + break; case KZ_SYSCALL_TYPE_DEBUG: p->un.debug.ret = thread_debug(p->un.debug.sockt); break; @@ -496,19 +510,16 @@ * これはOSの割り込み処理の再入になるが,以下の位置に限定して再入が行われる * ので問題は無い. */ - on_os_stack = 1; sigprocmask(SIG_UNBLOCK, &block, NULL); - sigprocmask(SIG_BLOCK, &block, NULL); - on_os_stack = 0; - - /* ここで SIGALRM が発生するとシグナルを取りこぼす...要検討 */ setcontext(¤t->context.uap); } static void thread_intr(int signo, siginfo_t *info, ucontext_t *uap) { - if (!on_os_stack) { + unsigned int esp = uap->uc_mcontext.mc_esp; + if ((esp < (unsigned int)intrstack.ss_sp) || + (esp >= (unsigned int)intrstack.ss_sp + intrstack.ss_size)) { memcpy(¤t->context.uap, uap, sizeof(ucontext_t)); } thread_intrvec(signo); @@ -517,19 +528,19 @@ static void thread_start(kz_func func, char *name, int pri, int argc, char *argv[]) { struct sigaction sa; - stack_t sigstack; memset(threads, 0, sizeof(threads)); memset(readyque, 0, sizeof(readyque)); memset(sigcalls, 0, sizeof(sigcalls)); + memset(handlers, 0, sizeof(handlers)); readyque_bitmap = 0; timers = NULL; - sigstack.ss_sp = malloc(SIGSTKSZ); - sigstack.ss_size = SIGSTKSZ; - sigstack.ss_flags = 0; - sigaltstack(&sigstack, NULL); + intrstack.ss_sp = malloc(SIGSTKSZ); + intrstack.ss_size = SIGSTKSZ; + intrstack.ss_flags = 0; + sigaltstack(&intrstack, NULL); memset(&sa, 0, sizeof(sa)); sa.sa_sigaction = (void (*)(int, siginfo_t *, void *))thread_intr;