diff -ruN kozos39/extintr.c kozos40/extintr.c --- kozos39/extintr.c Sun Feb 1 19:44:01 2009 +++ kozos40/extintr.c Sun Feb 1 23:23:47 2009 @@ -14,6 +14,9 @@ static int control_fd; /* 子プロセスへの制御用 */ +static int intrpri_current = 0; +static int intrpri_old = 0; + static struct timerreg { int read_fd; /* 子プロセスからの転送用 */ int cnt_fd; /* 子プロセスへの制御用 */ @@ -155,7 +158,8 @@ static void preproc(int id) { struct interrupts *intp; - int i, n; + int i, n, ns, ne; + static int old_n = -1; /* * 本関数は kz_precall() によりスレッドのディスパッチ前にOS内部から @@ -169,7 +173,18 @@ else n = intp - interrupts; - for (i = 0; i < EXTINTR_INTERRUPTS_NUM; i++) { + if (old_n == -1) { + ns = 0; + ne = EXTINTR_INTERRUPTS_NUM; + } else if (old_n < n) { + ns = old_n; + ne = n; + } else { + ns = n; + ne = old_n; + } + + for (i = ns; i < ne; i++) { intp = &interrupts[i]; if (intp->type == INTERRUPTS_TYPE_UNKNOWN) continue; @@ -179,6 +194,16 @@ intp->mask(intp); } + old_n = n; + + if (id) { + intrpri_old = intrpri_current; + intrpri_current = n; + if (extintr_id && (intrpri_current > intrpri_old)) { + kx_send(extintr_id, 0, NULL); + } + } + return; } @@ -349,7 +374,7 @@ { int i; struct interrupts *intp; - for (i = 0; i < EXTINTR_INTERRUPTS_NUM; i++) { + for (i = 0; i < intrpri_current; i++) { intp = &interrupts[i]; if (intp->type == INTERRUPTS_TYPE_UNKNOWN) continue; diff -ruN kozos39/thread.c kozos40/thread.c --- kozos39/thread.c Sun Feb 1 19:44:01 2009 +++ kozos40/thread.c Sun Feb 1 23:23:47 2009 @@ -390,6 +390,15 @@ static void srvcall_proc(kz_syscall_type_t type, kz_syscall_param_t *p) { + /* + * サービスコールなので current をNULLに設定する.(システムコールとサービス + * コールの内部で,システムコールの実行したスレッドIDを得るために current を + * 参照している部分があり(たとえば thread_send() など),current が残って + * いると誤動作する) + * サービスコール呼び出し後にスケジューリング処理が行われ, + * current は再設定される. + */ + current = NULL; syscall_procedure(type, p); } @@ -457,10 +466,6 @@ break; } extintr_proc(signo); - - if (current == NULL) { - return; - } current_old = NULL; while (1) {