diff -ruN kozos28/thread.c kozos29/thread.c --- kozos28/thread.c Wed Dec 12 20:44:00 2007 +++ kozos29/thread.c Wed Dec 12 21:42:51 2007 @@ -25,6 +25,7 @@ kz_thread *head; kz_thread *tail; } readyque[PRI_NUM]; +static unsigned int readyque_bitmap; static kz_timebuf *timers; static kz_thread *sigcalls[SIG_NUM]; static int debug_sockt = 0; @@ -36,8 +37,10 @@ static void getcurrent() { readyque[current->pri].head = current->next; - if (readyque[current->pri].head == NULL) + if (readyque[current->pri].head == NULL) { readyque[current->pri].tail = NULL; + readyque_bitmap &= ~(1 << current->pri); + } current->flags &= ~KZ_THREAD_FLAG_RUNNING; current->next = NULL; } @@ -55,6 +58,7 @@ readyque[current->pri].head = current; } readyque[current->pri].tail = current; + readyque_bitmap |= (1 << current->pri); current->flags |= KZ_THREAD_FLAG_RUNNING; return 0; @@ -420,15 +424,34 @@ static void schedule() { - int i; - for (i = 0; i < PRI_NUM; i++) { - if (readyque[i].head) break; +#if PRI_NUM > 32 +#error ビットマップを配列化する必要あり +#endif + unsigned int bitmap = readyque_bitmap; + int n = 0; + static int bitmap2num[16] = { + -32, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 + }; + + if (!(bitmap & 0xffff)) { + bitmap >>= 16; + n += 16; + } + if (!(bitmap & 0xff)) { + bitmap >>= 8; + n += 8; + } + if (!(bitmap & 0xf)) { + bitmap >>= 4; + n += 4; } - if (i == PRI_NUM) { + n += bitmap2num[bitmap & 0xf]; + if (n < 0) { /* 実行可能なスレッドが存在しないので,終了する */ exit(0); } - current = readyque[i].head; + + current = readyque[n].head; } static void thread_intrvec(int signo) @@ -500,6 +523,7 @@ memset(readyque, 0, sizeof(readyque)); memset(sigcalls, 0, sizeof(sigcalls)); + readyque_bitmap = 0; timers = NULL; sigstack.ss_sp = malloc(SIGSTKSZ);