diff -ruN kozos11/stublib.c kozos12/stublib.c --- kozos11/stublib.c Sat Nov 10 16:10:31 2007 +++ kozos12/stublib.c Sat Nov 10 16:10:33 2007 @@ -100,22 +100,43 @@ void stub_store_regs(kz_thread *thp) { memset(registers, 0, sizeof(registers)); - registers[PC] = thp->context.env[0]._jb[0]; /* EIP */ - registers[EBX] = thp->context.env[0]._jb[1]; /* EBX */ - registers[ESP] = thp->context.env[0]._jb[2]; /* ESP */ - registers[EBP] = thp->context.env[0]._jb[3]; /* EBP */ - registers[ESI] = thp->context.env[0]._jb[4]; /* ESI */ - registers[EDI] = thp->context.env[0]._jb[5]; /* EDI */ + + registers[EAX] = thp->context.uap.uc_mcontext.mc_eax; + registers[ECX] = thp->context.uap.uc_mcontext.mc_ecx; + registers[EDX] = thp->context.uap.uc_mcontext.mc_edx; + registers[EBX] = thp->context.uap.uc_mcontext.mc_ebx; + registers[ESP] = thp->context.uap.uc_mcontext.mc_esp; + registers[EBP] = thp->context.uap.uc_mcontext.mc_ebp; + registers[ESI] = thp->context.uap.uc_mcontext.mc_esi; + registers[EDI] = thp->context.uap.uc_mcontext.mc_edi; + registers[PC] = thp->context.uap.uc_mcontext.mc_eip; + registers[PS] = thp->context.uap.uc_mcontext.mc_eflags; + registers[CS] = thp->context.uap.uc_mcontext.mc_cs; + registers[SS] = thp->context.uap.uc_mcontext.mc_ss; + registers[DS] = thp->context.uap.uc_mcontext.mc_ds; + registers[ES] = thp->context.uap.uc_mcontext.mc_es; + registers[FS] = thp->context.uap.uc_mcontext.mc_fs; + registers[GS] = thp->context.uap.uc_mcontext.mc_gs; } void stub_restore_regs(kz_thread *thp) { - thp->context.env[0]._jb[0] = registers[PC]; /* EIP */ - thp->context.env[0]._jb[1] = registers[EBX]; /* EBX */ - thp->context.env[0]._jb[2] = registers[ESP]; /* ESP */ - thp->context.env[0]._jb[3] = registers[EBP]; /* EBP */ - thp->context.env[0]._jb[4] = registers[ESI]; /* ESI */ - thp->context.env[0]._jb[5] = registers[EDI]; /* EDI */ + thp->context.uap.uc_mcontext.mc_eax = registers[EAX]; + thp->context.uap.uc_mcontext.mc_ecx = registers[ECX]; + thp->context.uap.uc_mcontext.mc_edx = registers[EDX]; + thp->context.uap.uc_mcontext.mc_ebx = registers[EBX]; + thp->context.uap.uc_mcontext.mc_esp = registers[ESP]; + thp->context.uap.uc_mcontext.mc_ebp = registers[EBP]; + thp->context.uap.uc_mcontext.mc_esi = registers[ESI]; + thp->context.uap.uc_mcontext.mc_edi = registers[EDI]; + thp->context.uap.uc_mcontext.mc_eip = registers[PC]; + thp->context.uap.uc_mcontext.mc_eflags = registers[PS]; + thp->context.uap.uc_mcontext.mc_cs = registers[CS]; + thp->context.uap.uc_mcontext.mc_ss = registers[SS]; + thp->context.uap.uc_mcontext.mc_ds = registers[DS]; + thp->context.uap.uc_mcontext.mc_es = registers[ES]; + thp->context.uap.uc_mcontext.mc_fs = registers[FS]; + thp->context.uap.uc_mcontext.mc_gs = registers[GS]; } int stub_proc(kz_thread *thp, int signo) diff -ruN kozos11/thread.c kozos12/thread.c --- kozos11/thread.c Sat Nov 10 16:10:31 2007 +++ kozos12/thread.c Sat Nov 10 16:10:33 2007 @@ -4,6 +4,7 @@ #include #include #include +#include #include #include "kozos.h" @@ -26,6 +27,7 @@ static kz_timebuf *timers; static kz_thread *sigcalls[SIG_NUM]; static int debug_sockt = 0; +static sigset_t block; kz_thread *current; @@ -429,8 +431,10 @@ longjmp(current->context.env, 1); } -static void thread_intr(int signo) +static void thread_intr(int signo, siginfo_t *info, ucontext_t *uap) { + memcpy(¤t->context.uap, uap, sizeof(ucontext_t)); + /* * setjmp()/longjmp() はシグナルマスクを保存し復元するが, * _setjmp()/_longjmp() はシグナルマスクを保存しない. @@ -439,23 +443,32 @@ if (setjmp(current->context.env) == 0) { longjmp(intr_env, signo); } + + setcontext(¤t->context.uap); } static void thread_start(kz_func func, char *name, int pri, int argc, char *argv[]) { + struct sigaction sa; + memset(threads, 0, sizeof(threads)); memset(readyque, 0, sizeof(readyque)); memset(sigcalls, 0, sizeof(sigcalls)); timers = NULL; - signal(SIGSYS, thread_intr); - signal(SIGHUP, thread_intr); - signal(SIGALRM, thread_intr); - signal(SIGBUS, thread_intr); - signal(SIGSEGV, thread_intr); - signal(SIGTRAP, thread_intr); - signal(SIGILL, thread_intr); + memset(&sa, 0, sizeof(sa)); + sa.sa_sigaction = (void (*)(int, siginfo_t *, void *))thread_intr; + sa.sa_flags |= SA_SIGINFO; + sa.sa_mask = block; + + sigaction(SIGSYS , &sa, NULL); + sigaction(SIGHUP , &sa, NULL); + sigaction(SIGALRM, &sa, NULL); + sigaction(SIGBUS , &sa, NULL); + sigaction(SIGSEGV, &sa, NULL); + sigaction(SIGTRAP, &sa, NULL); + sigaction(SIGILL , &sa, NULL); /* * current 未定のためにシステムコール発行はできないので, @@ -470,6 +483,24 @@ void kz_start(kz_func func, char *name, int pri, int argc, char *argv[]) { int signo; + + /* + * setjmp()/longjmp()はシグナルマスクを保存/復旧するので, + * intr_env の setjmp() 前にシグナルマスクを設定することでシグナル処理中の + * シグナルの発生をマスクし,割り込みハンドラ内でのシグナルを無効とする. + * (でないと割り込みハンドラの実行中に intr_env に longjmp() した後に, + * SIGALRM や SIGHUP の発生をハンドリングしてスレッドのディスパッチが + * 行われてしまい,誤動作する) + */ + sigemptyset(&block); + sigaddset(&block, SIGSYS); + sigaddset(&block, SIGHUP); + sigaddset(&block, SIGALRM); + sigaddset(&block, SIGBUS); + sigaddset(&block, SIGSEGV); + sigaddset(&block, SIGTRAP); + sigaddset(&block, SIGILL); + sigprocmask(SIG_BLOCK, &block, NULL); /* * setjmp()は最低位の関数から呼ぶ必要があるので,本体は thread_start() に diff -ruN kozos11/thread.h kozos12/thread.h --- kozos11/thread.h Sat Nov 10 16:10:31 2007 +++ kozos12/thread.h Sat Nov 10 16:10:33 2007 @@ -4,6 +4,7 @@ #include #include #include +#include #include "kozos.h" #include "syscall.h" @@ -36,6 +37,7 @@ struct { jmp_buf env; + ucontext_t uap; } context; } kz_thread;