diff -ruN kozos37/extintr.c kozos38/extintr.c --- kozos37/extintr.c Mon Jan 26 21:44:44 2009 +++ kozos38/extintr.c Mon Jan 26 22:57:44 2009 @@ -43,6 +43,8 @@ struct consreg *cons; } regs; + int (*mask)(struct interrupts *intp); + int (*unmask)(struct interrupts *intp); int (*checkintr)(struct interrupts *intp); int (*intr)(struct interrupts *intp); int (*command)(struct interrupts *intp, int id, int size, char *command); @@ -139,6 +141,68 @@ return 0; } +static struct interrupts *interrupts_search(int id) +{ + int i; + struct interrupts *intp; + for (i = 0; i < EXTINTR_INTERRUPTS_NUM; i++) { + intp = &interrupts[i]; + if (intp->id == id) return intp; + } + return NULL; +} + +static void preproc(int id) +{ + struct interrupts *intp; + int i, n; + + /* + * 本関数は kz_precall() によりスレッドのディスパッチ前にOS内部から + * 呼ばれるので,システムコールを利用してはいけない. + */ + + if (id == 0) + n = 0; + else if ((intp = interrupts_search(id)) == NULL) + n = EXTINTR_INTERRUPTS_NUM; + else + n = intp - interrupts; + + for (i = 0; i < EXTINTR_INTERRUPTS_NUM; i++) { + intp = &interrupts[i]; + if (intp->type == INTERRUPTS_TYPE_UNKNOWN) + continue; + if (i < n) + intp->unmask(intp); + else + intp->mask(intp); + } + + return; +} + +static void allmask(int id) +{ + preproc(0); +} + +static int timer_mask(struct interrupts *intp) +{ + char c; + c = EXTINTR_CMD_TIMER_MASK; + write(intp->regs.timer->cnt_fd, &c, 1); + return 0; +} + +static int timer_unmask(struct interrupts *intp) +{ + char c; + c = EXTINTR_CMD_TIMER_UNMASK; + write(intp->regs.timer->cnt_fd, &c, 1); + return 0; +} + static int timer_checkintr(struct interrupts *intp) { return extintr_checkfd(intp->regs.timer->read_fd); @@ -160,6 +224,7 @@ switch (command[0]) { case EXTINTR_CMD_TIMER_USE: intp->id = id; + kz_precall(id, preproc); break; case EXTINTR_CMD_TIMER_START: @@ -187,6 +252,8 @@ static int timer_init(struct interrupts *intp) { intp->type = INTERRUPTS_TYPE_TIMER; + intp->mask = timer_mask; + intp->unmask = timer_unmask; intp->checkintr = timer_checkintr; intp->intr = timer_intr; intp->command = timer_command; @@ -194,6 +261,22 @@ return 0; } +static int cons_mask(struct interrupts *intp) +{ + char c; + c = EXTINTR_CMD_CONSOLE_DISABLE; + write(intp->regs.cons->cnt_fd, &c, 1); + return 0; +} + +static int cons_unmask(struct interrupts *intp) +{ + char c; + c = EXTINTR_CMD_CONSOLE_ENABLE; + write(intp->regs.cons->cnt_fd, &c, 1); + return 0; +} + static int cons_checkintr(struct interrupts *intp) { return extintr_checkfd(intp->regs.cons->read_fd); @@ -219,6 +302,7 @@ switch (command[0]) { case EXTINTR_CMD_CONSOLE_USE: /* コンソールの利用 */ intp->id = id; + kz_precall(id, preproc); break; case EXTINTR_CMD_CONSOLE_ENABLE: @@ -245,6 +329,8 @@ static int cons_init(struct interrupts *intp) { intp->type = INTERRUPTS_TYPE_CONSOLE; + intp->mask = cons_mask; + intp->unmask = cons_unmask; intp->checkintr = cons_checkintr; intp->intr = cons_intr; intp->command = cons_command; @@ -354,6 +440,9 @@ extintr_intr_regist(&interrupts[5], & consreg[2], cons_init); extintr_intr_regist(&interrupts[6], &timerreg[3], timer_init); extintr_intr_regist(&interrupts[7], & consreg[3], cons_init); + + kz_precall(0, preproc); + kz_precall(kz_getid(), allmask); extintr_mainloop(); diff -ruN kozos37/main.c kozos38/main.c --- kozos37/main.c Thu Jan 22 19:52:33 2009 +++ kozos38/main.c Mon Jan 26 22:57:44 2009 @@ -9,13 +9,13 @@ #if 0 stubd_id = kz_run(stubd_main, "stubd", 2, 0, NULL); #endif - outlog_id = kz_run(outlog_main, "outlog", 3, 0, NULL); - timerd_id = kz_run(timerd_main, "timerd", 4, 0, NULL); + outlog_id = kz_run(outlog_main, "outlog", 20, 0, NULL); + timerd_id = kz_run(timerd_main, "timerd", 12, 0, NULL); idle_id = kz_run(idle_main, "idle", 31, 0, NULL); - clock_id = kz_run(clock_main, "clock", 7, 0, NULL); - clock2_id = kz_run(clock2_main, "clock2", 7, 0, NULL); - clock3_id = kz_run(clock3_main, "clock3", 7, 0, NULL); - command_id = kz_run(command_main, "command", 8, 0, NULL); + clock_id = kz_run(clock_main, "clock", 10, 0, NULL); + clock2_id = kz_run(clock2_main, "clock2", 21, 0, NULL); + clock3_id = kz_run(clock3_main, "clock3", 21, 0, NULL); + command_id = kz_run(command_main, "command", 11, 0, NULL); return 0; } diff -ruN kozos37/thread.c kozos38/thread.c --- kozos37/thread.c Thu Jan 22 19:52:33 2009 +++ kozos38/thread.c Mon Jan 26 22:57:44 2009 @@ -27,6 +27,7 @@ static sigset_t block_old; static int block_count = 0; static stack_t intrstack; +static kz_prefunc default_precall = NULL; kz_thread *current; @@ -290,7 +291,10 @@ static int thread_precall(int id, kz_prefunc func) { kz_thread *thp = (kz_thread *)id; - thp->precall = func; + if (thp) + thp->precall = func; + else + default_precall = func; putcurrent(); return 0; } @@ -469,6 +473,8 @@ if (current->precall) { current->precall((int)current); + } else if (default_precall) { + default_precall((int)current); } /* diff -ruN kozos37/timerd.c kozos38/timerd.c --- kozos37/timerd.c Fri Jan 23 22:04:58 2009 +++ kozos38/timerd.c Mon Jan 26 22:57:44 2009 @@ -52,7 +52,7 @@ timebuf **tmpp; timebuf *tmp; struct timeval tm; - int diffmsec; + int s, diffmsec; tmp = kz_kmalloc(sizeof(*tmp)); tmp->next = NULL; @@ -60,8 +60,9 @@ gettimeofday(&tm, NULL); if (timers) { - diffmsec = (tm.tv_sec - alarm_tm.tv_sec) * 1000 + - (tm.tv_usec - alarm_tm.tv_usec) / 1000; + s = tm.tv_usec < alarm_tm.tv_usec ? 1 : 0; + diffmsec = (-s + tm.tv_sec - alarm_tm.tv_sec) * 1000 + + (s * 1000000 + tm.tv_usec - alarm_tm.tv_usec) / 1000; if (timers->msec > diffmsec) timers->msec -= diffmsec; else