--- Gnu-Mach/kern/sched_prim.c 2020/09/02 04:36:56 1.1 +++ Gnu-Mach/kern/sched_prim.c 2020/09/02 04:51:54 1.1.1.6 @@ -1,25 +1,25 @@ -/* +/* * Mach Operating System * Copyright (c) 1993-1987 Carnegie Mellon University * All Rights Reserved. - * + * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. - * + * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * + * * Carnegie Mellon requests users of this software to return to - * + * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 - * + * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ @@ -32,20 +32,19 @@ * */ -#include -#include -#include -#include -#include -#include -#include - +#include #include +#include +#include /* For def'n of splsched() */ +#include #include #include #include +#include #include -#include +#include +#include +#include #include #include #include @@ -53,19 +52,14 @@ #include #include #include -#include #include #include #include -#include /* For def'n of splsched() */ #if MACH_FIXPRI #include #endif /* MACH_FIXPRI */ - -extern int hz; - int min_quantum; /* defines max context switch rate */ unsigned sched_tick; @@ -76,20 +70,8 @@ int sched_usec; thread_t sched_thread_id; -void recompute_priorities(void); /* forward */ -void update_priority(thread_t); -void set_pri(thread_t, int, boolean_t); -void do_thread_scan(void); - -thread_t choose_pset_thread(); - timer_elt_data_t recompute_priorities_timer; -#if DEBUG -void checkrq(run_queue_t, char *); -void thread_check(thread_t, run_queue_t); -#endif - /* * State machine * @@ -99,7 +81,7 @@ void thread_check(thread_t, run_queue_t) * S suspended (or will suspend) * N non-interruptible * - * init action + * init action * assert_wait thread_block clear_wait suspend resume * * R RW, RWN R; setrun - RS - @@ -147,18 +129,18 @@ void thread_check(thread_t, run_queue_t) * The wait event hash table declarations are as follows: */ -#define NUMQUEUES 59 +#define NUMQUEUES 1031 queue_head_t wait_queue[NUMQUEUES]; decl_simple_lock_data(, wait_lock[NUMQUEUES]) /* NOTE: we want a small positive integer out of this */ #define wait_hash(event) \ - ((((int)(event) < 0) ? ~(int)(event) : (int)(event)) % NUMQUEUES) + ((((long)(event) < 0) ? ~(long)(event) : (long)(event)) % NUMQUEUES) void wait_queue_init(void) { - register int i; + int i; for (i = 0; i < NUMQUEUES; i++) { queue_init(&wait_queue[i]); @@ -168,12 +150,12 @@ void wait_queue_init(void) void sched_init(void) { - recompute_priorities_timer.fcn = (int (*)())recompute_priorities; - recompute_priorities_timer.param = (char *)0; + recompute_priorities_timer.fcn = recompute_priorities; + recompute_priorities_timer.param = NULL; min_quantum = hz / 10; /* context switch 10 times/second */ wait_queue_init(); - pset_sys_bootstrap(); /* initialize processer mgmt. */ + pset_sys_bootstrap(); /* initialize processor mgmt. */ queue_init(&action_queue); simple_lock_init(&action_lock); sched_tick = 0; @@ -188,8 +170,9 @@ void sched_init(void) * Called at splsoftclock. */ void thread_timeout( - thread_t thread) + void *_thread) { + thread_t thread = _thread; assert(thread->timer.set == TELT_UNSET); clear_wait(thread, THREAD_TIMED_OUT, FALSE); @@ -202,12 +185,12 @@ void thread_timeout( * is ready to wait. Must be called between assert_wait() * and thread_block(). */ - + void thread_set_timeout( int t) /* timeout interval in ticks */ { - register thread_t thread = current_thread(); - register spl_t s; + thread_t thread = current_thread(); + spl_t s; s = splsched(); thread_lock(thread); @@ -222,12 +205,12 @@ void thread_set_timeout( * Set up thread timeout element when thread is created. */ void thread_timeout_setup( - register thread_t thread) + thread_t thread) { - thread->timer.fcn = (int (*)())thread_timeout; - thread->timer.param = (char *)thread; - thread->depress_timer.fcn = (int (*)())thread_depress_timeout; - thread->depress_timer.param = (char *)thread; + thread->timer.fcn = thread_timeout; + thread->timer.param = thread; + thread->depress_timer.fcn = (void (*)(void*))thread_depress_timeout; + thread->depress_timer.param = thread; } /* @@ -240,12 +223,10 @@ void assert_wait( event_t event, boolean_t interruptible) { - register queue_t q; - register int index; - register thread_t thread; -#if MACH_SLOCKS - register simple_lock_t lock; -#endif /* MACH_SLOCKS */ + queue_t q; + int index; + thread_t thread; + decl_simple_lock_data( , *lock); spl_t s; thread = current_thread(); @@ -257,12 +238,10 @@ void assert_wait( if (event != 0) { index = wait_hash(event); q = &wait_queue[index]; -#if MACH_SLOCKS lock = &wait_lock[index]; -#endif /* MACH_SLOCKS */ simple_lock(lock); thread_lock(thread); - enqueue_tail(q, (queue_entry_t) thread); + enqueue_tail(q, &(thread->links)); thread->wait_event = event; if (interruptible) thread->state |= TH_WAIT; @@ -295,16 +274,14 @@ void assert_wait( * interruptible. */ void clear_wait( - register thread_t thread, + thread_t thread, int result, boolean_t interrupt_only) { - register int index; - register queue_t q; -#if MACH_SLOCKS - register simple_lock_t lock; -#endif /* MACH_SLOCKS */ - register event_t event; + int index; + queue_t q; + decl_simple_lock_data( , *lock); + event_t event; spl_t s; s = splsched(); @@ -323,9 +300,7 @@ void clear_wait( thread_unlock(thread); index = wait_hash(event); q = &wait_queue[index]; -#if MACH_SLOCKS lock = &wait_lock[index]; -#endif /* MACH_SLOCKS */ simple_lock(lock); /* * If the thread is still waiting on that event, @@ -342,7 +317,7 @@ void clear_wait( simple_unlock(lock); } if (event == 0) { - register int state = thread->state; + int state = thread->state; reset_timeout_check(&thread->timer); @@ -382,6 +357,13 @@ void clear_wait( splx(s); } +static inline void __attribute__((noreturn)) +state_panic(const thread_t thread, const char *caller) +{ + panic ("%s: thread %x has unexpected state %x", + caller, thread, thread->state); +} + /* * thread_wakeup_prim: * @@ -394,21 +376,17 @@ void thread_wakeup_prim( boolean_t one_thread, int result) { - register queue_t q; - register int index; - register thread_t thread, next_th; -#if MACH_SLOCKS - register simple_lock_t lock; -#endif /* MACH_SLOCKS */ + queue_t q; + int index; + thread_t thread, next_th; + decl_simple_lock_data( , *lock); spl_t s; - register int state; + int state; index = wait_hash(event); q = &wait_queue[index]; s = splsched(); -#if MACH_SLOCKS lock = &wait_lock[index]; -#endif /* MACH_SLOCKS */ simple_lock(lock); thread = (thread_t) queue_first(q); while (!queue_end(q, (queue_entry_t)thread)) { @@ -448,7 +426,7 @@ void thread_wakeup_prim( break; default: - panic("thread_wakeup"); + state_panic(thread, "thread_wakeup"); break; } thread_unlock(thread); @@ -468,6 +446,9 @@ void thread_wakeup_prim( * occurs. The specified lock is unlocked before releasing * the cpu. (This is a convenient way to sleep without manually * calling assert_wait). + * + * Note: if the event may be woken from an interrupt handler, this must be + * called at an spl level that prevents such interrupts. */ void thread_sleep( event_t event, @@ -476,7 +457,7 @@ void thread_sleep( { assert_wait(event, interruptible); /* assert event */ simple_unlock(lock); /* release the lock */ - thread_block((void (*)()) 0); /* block ourselves */ + thread_block(thread_no_continuation); /* block ourselves */ } /* @@ -490,8 +471,8 @@ void thread_sleep( * xxx - DO NOT export this to users. */ void thread_bind( - register thread_t thread, - processor_t processor) + thread_t thread, + processor_t processor) { spl_t s; @@ -509,9 +490,9 @@ void thread_bind( */ thread_t thread_select( - register processor_t myprocessor) + processor_t myprocessor) { - register thread_t thread; + thread_t thread; myprocessor->first_quantum = TRUE; /* @@ -523,7 +504,7 @@ thread_t thread_select( myprocessor->quantum = min_quantum; } else { - register processor_set_t pset; + processor_set_t pset; #if MACH_HOST pset = myprocessor->processor_set; @@ -559,7 +540,7 @@ thread_t thread_select( } } else { - register queue_t q; + queue_t q; /* * If there is a thread at hint, grab it, @@ -622,9 +603,9 @@ thread_t thread_select( */ boolean_t thread_invoke( - register thread_t old_thread, - continuation_t continuation, - register thread_t new_thread) + thread_t old_thread, + continuation_t continuation, + thread_t new_thread) { /* * Check for invoking the same thread. @@ -637,8 +618,9 @@ boolean_t thread_invoke( thread_lock(new_thread); new_thread->state &= ~TH_UNINT; thread_unlock(new_thread); + thread_wakeup(TH_EV_STATE(new_thread)); - if (continuation != (void (*)()) 0) { + if (continuation != thread_no_continuation) { (void) spl0(); call_continuation(continuation); /*NOTREACHED*/ @@ -651,13 +633,14 @@ boolean_t thread_invoke( */ thread_lock(new_thread); if ((old_thread->stack_privilege != current_stack()) && - (continuation != (void (*)()) 0)) + (continuation != thread_no_continuation)) { switch (new_thread->state & TH_SWAP_STATE) { case TH_SWAPPED: new_thread->state &= ~(TH_SWAPPED | TH_UNINT); thread_unlock(new_thread); + thread_wakeup(TH_EV_STATE(new_thread)); #if NCPUS > 1 new_thread->last_processor = current_processor(); @@ -696,7 +679,7 @@ boolean_t thread_invoke( if (old_thread->wake_active) { old_thread->wake_active = FALSE; thread_unlock(old_thread); - thread_wakeup((event_t)&old_thread->wake_active); + thread_wakeup(TH_EV_WAKE_ACTIVE(old_thread)); goto after_old_thread; } @@ -733,7 +716,7 @@ boolean_t thread_invoke( break; default: - panic("thread_invoke"); + state_panic(old_thread, "thread_invoke"); } thread_unlock(old_thread); after_old_thread: @@ -746,7 +729,7 @@ boolean_t thread_invoke( * running out of stack. */ - counter_always(c_thread_invoke_hits++); + counter(c_thread_invoke_hits++); (void) spl0(); call_continuation(new_thread->swap_func); /*NOTREACHED*/ @@ -758,7 +741,7 @@ boolean_t thread_invoke( */ thread_swapin(new_thread); thread_unlock(new_thread); - counter_always(c_thread_invoke_misses++); + counter(c_thread_invoke_misses++); return FALSE; case 0: @@ -779,7 +762,7 @@ boolean_t thread_invoke( { thread_swapin(new_thread); thread_unlock(new_thread); - counter_always(c_thread_invoke_misses++); + counter(c_thread_invoke_misses++); return FALSE; } } @@ -787,6 +770,7 @@ boolean_t thread_invoke( new_thread->state &= ~(TH_SWAPPED | TH_UNINT); thread_unlock(new_thread); + thread_wakeup(TH_EV_STATE(new_thread)); /* * Thread is now interruptible. @@ -807,7 +791,7 @@ boolean_t thread_invoke( * changing address spaces. It updates active_threads. * It returns only if a continuation is not supplied. */ - counter_always(c_thread_invoke_csw++); + counter(c_thread_invoke_csw++); old_thread = switch_context(old_thread, continuation, new_thread); /* @@ -826,9 +810,9 @@ boolean_t thread_invoke( * Called at splsched. */ void thread_continue( - register thread_t old_thread) + thread_t old_thread) { - register continuation_t continuation = current_thread()->swap_func; + continuation_t continuation = current_thread()->swap_func; /* * We must dispatch the old thread and then @@ -862,9 +846,9 @@ void thread_continue( void thread_block( continuation_t continuation) { - register thread_t thread = current_thread(); - register processor_t myprocessor = cpu_to_processor(cpu_number()); - register thread_t new_thread; + thread_t thread = current_thread(); + processor_t myprocessor = cpu_to_processor(cpu_number()); + thread_t new_thread; spl_t s; check_simple_locks(); @@ -879,7 +863,7 @@ void thread_block( recover_ras(thread); } #endif /* FAST_TAS */ - + ast_off(cpu_number(), AST_BLOCK); do @@ -903,10 +887,10 @@ void thread_block( */ void thread_run( continuation_t continuation, - register thread_t new_thread) + thread_t new_thread) { - register thread_t thread = current_thread(); - register processor_t myprocessor = cpu_to_processor(cpu_number()); + thread_t thread = current_thread(); + processor_t myprocessor = cpu_to_processor(cpu_number()); spl_t s; check_simple_locks(); @@ -925,7 +909,7 @@ void thread_run( */ void thread_dispatch( - register thread_t thread) + thread_t thread) { /* * If we are discarding the thread's stack, we must do it @@ -934,7 +918,7 @@ void thread_dispatch( thread_lock(thread); - if (thread->swap_func != (void (*)()) 0) { + if (thread->swap_func != thread_no_continuation) { assert((thread->state & TH_SWAP_STATE) == 0); thread->state |= TH_SWAPPED; stack_free(thread); @@ -951,7 +935,7 @@ void thread_dispatch( if (thread->wake_active) { thread->wake_active = FALSE; thread_unlock(thread); - thread_wakeup((event_t)&thread->wake_active); + thread_wakeup(TH_EV_WAKE_ACTIVE(thread)); return; } break; @@ -982,7 +966,7 @@ void thread_dispatch( break; default: - panic("thread_dispatch"); + state_panic(thread, "thread_dispatch"); } thread_unlock(thread); } @@ -1017,7 +1001,7 @@ shift_data_t wait_shift[32] = { (pri) = (th)->priority /* start with base priority */ \ + ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)) \ + ((th)->sched_usage >> (PRI_SHIFT_2 + SCHED_SHIFT)); \ - if ((pri) > 31) (pri) = 31; \ + if ((pri) > NRQS - 1) (pri) = NRQS - 1; \ MACRO_END #else /* PRI_SHIFT_2 */ #define do_priority_computation(th, pri) \ @@ -1025,7 +1009,7 @@ shift_data_t wait_shift[32] = { (pri) = (th)->priority /* start with base priority */ \ + ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)) \ - ((th)->sched_usage >> (SCHED_SHIFT - PRI_SHIFT_2)); \ - if ((pri) > 31) (pri) = 31; \ + if ((pri) > NRQS - 1) (pri) = NRQS - 1; \ MACRO_END #endif /* PRI_SHIFT_2 */ #else /* defined(PRI_SHIFT_2) */ @@ -1033,7 +1017,7 @@ shift_data_t wait_shift[32] = { MACRO_BEGIN \ (pri) = (th)->priority /* start with base priority */ \ + ((th)->sched_usage >> (PRI_SHIFT + SCHED_SHIFT)); \ - if ((pri) > 31) (pri) = 31; \ + if ((pri) > NRQS - 1) (pri) = NRQS - 1; \ MACRO_END #endif /* defined(PRI_SHIFT_2) */ @@ -1046,14 +1030,14 @@ shift_data_t wait_shift[32] = { * Take the base priority for this thread and add * to it an increment derived from its cpu_usage. * - * The thread *must* be locked by the caller. + * The thread *must* be locked by the caller. */ void compute_priority( - register thread_t thread, + thread_t thread, boolean_t resched) { - register int pri; + int pri; #if MACH_FIXPRI if (thread->policy == POLICY_TIMESHARE) { @@ -1082,9 +1066,9 @@ void compute_priority( */ void compute_my_priority( - register thread_t thread) + thread_t thread) { - register int temp_pri; + int temp_pri; do_priority_computation(thread,temp_pri); thread->sched_pri = temp_pri; @@ -1095,7 +1079,7 @@ void compute_my_priority( * * Update the priorities of all threads periodically. */ -void recompute_priorities(void) +void recompute_priorities(void *param) { #if SIMPLE_CLOCK int new_usec; @@ -1123,17 +1107,17 @@ void recompute_priorities(void) /* * update_priority * - * Cause the priority computation of a thread that has been + * Cause the priority computation of a thread that has been * sleeping or suspended to "catch up" with the system. Thread * *MUST* be locked by caller. If thread is running, then this * can only be called by the thread on itself. */ void update_priority( - register thread_t thread) + thread_t thread) { - register unsigned int ticks; - register shift_t shiftp; - register int temp_pri; + unsigned int ticks; + shift_t shiftp; + int temp_pri; ticks = sched_tick - thread->sched_stamp; @@ -1193,7 +1177,7 @@ void update_priority( #if DEBUG #define run_queue_enqueue(rq, th) \ MACRO_BEGIN \ - register unsigned int whichq; \ + unsigned int whichq; \ \ whichq = (th)->sched_pri; \ if (whichq >= NRQS) { \ @@ -1203,7 +1187,7 @@ void update_priority( \ simple_lock(&(rq)->lock); /* lock the run queue */ \ checkrq((rq), "thread_setrun: before adding thread"); \ - enqueue_tail(&(rq)->runq[whichq], (queue_entry_t) (th)); \ + enqueue_tail(&(rq)->runq[whichq], &((th)->links)); \ \ if (whichq < (rq)->low || (rq)->count == 0) \ (rq)->low = whichq; /* minimize */ \ @@ -1217,7 +1201,7 @@ void update_priority( #else /* DEBUG */ #define run_queue_enqueue(rq, th) \ MACRO_BEGIN \ - register unsigned int whichq; \ + unsigned int whichq; \ \ whichq = (th)->sched_pri; \ if (whichq >= NRQS) { \ @@ -1226,7 +1210,7 @@ void update_priority( } \ \ simple_lock(&(rq)->lock); /* lock the run queue */ \ - enqueue_tail(&(rq)->runq[whichq], (queue_entry_t) (th)); \ + enqueue_tail(&(rq)->runq[whichq], &((th)->links)); \ \ if (whichq < (rq)->low || (rq)->count == 0) \ (rq)->low = whichq; /* minimize */ \ @@ -1246,13 +1230,13 @@ void update_priority( */ void thread_setrun( - register thread_t th, + thread_t th, boolean_t may_preempt) { - register processor_t processor; - register run_queue_t rq; + processor_t processor; + run_queue_t rq; #if NCPUS > 1 - register processor_set_t pset; + processor_set_t pset; #endif /* NCPUS > 1 */ /* @@ -1420,7 +1404,7 @@ void set_pri( int pri, boolean_t resched) { - register struct run_queue *rq; + struct run_queue *rq; rq = rem_runq(th); th->sched_pri = pri; @@ -1445,7 +1429,7 @@ void set_pri( struct run_queue *rem_runq( thread_t th) { - register struct run_queue *rq; + struct run_queue *rq; rq = th->runq; /* @@ -1511,10 +1495,10 @@ thread_t choose_thread( processor_t myprocessor) { thread_t th; - register queue_t q; - register run_queue_t runq; - register int i; - register processor_set_t pset; + queue_t q; + run_queue_t runq; + int i; + processor_set_t pset; runq = &myprocessor->runq; @@ -1555,13 +1539,13 @@ thread_t choose_thread( */ thread_t choose_pset_thread( - register processor_t myprocessor, + processor_t myprocessor, processor_set_t pset) { - register run_queue_t runq; - register thread_t th; - register queue_t q; - register int i; + run_queue_t runq; + thread_t th; + queue_t q; + int i; runq = &pset->runq; @@ -1637,14 +1621,14 @@ int no_dispatch_count = 0; * to execute. */ -void idle_thread_continue(void) +void __attribute__((noreturn)) idle_thread_continue(void) { - register processor_t myprocessor; - register volatile thread_t *threadp; - register volatile int *gcount; - register volatile int *lcount; - register thread_t new_thread; - register int state; + processor_t myprocessor; + volatile thread_t *threadp; + volatile int *gcount; + volatile int *lcount; + thread_t new_thread; + int state; int mycpu; spl_t s; @@ -1681,7 +1665,7 @@ void idle_thread_continue(void) ast_taken(); /* back at spl0 */ } - + /* * machine_idle is a machine dependent function, * to conserve power. @@ -1743,7 +1727,7 @@ retry: thread_run(idle_thread_continue, new_thread); } else if (state == PROCESSOR_IDLE) { - register processor_set_t pset; + processor_set_t pset; pset = myprocessor->processor_set; simple_lock(&pset->idle_lock); @@ -1794,14 +1778,14 @@ retry: void idle_thread(void) { - register thread_t self = current_thread(); + thread_t self = current_thread(); spl_t s; stack_privilege(self); s = splsched(); - self->priority = 31; - self->sched_pri = 31; + self->priority = NRQS-1; + self->sched_pri = NRQS-1; /* * Set the idle flag to indicate that this is an idle thread, @@ -1897,10 +1881,10 @@ boolean_t do_runq_scan( run_queue_t runq) { - register spl_t s; - register queue_t q; - register thread_t thread; - register int count; + spl_t s; + queue_t q; + thread_t thread; + int count; s = splsched(); simple_lock(&runq->lock); @@ -1945,7 +1929,7 @@ do_runq_scan( stuck_threads[stuck_count++] = thread; if (do_thread_scan_debug) - printf("do_runq_scan: adding thread %#x\n", thread); + printf("do_runq_scan: adding thread %p\n", thread); } count--; thread = next; @@ -1961,11 +1945,11 @@ if (do_thread_scan_debug) void do_thread_scan(void) { - register spl_t s; - register boolean_t restart_needed = 0; - register thread_t thread; + spl_t s; + boolean_t restart_needed = 0; + thread_t thread; #if MACH_HOST - register processor_set_t pset; + processor_set_t pset; #endif /* MACH_HOST */ do { @@ -2005,16 +1989,16 @@ void do_thread_scan(void) } } while (restart_needed); } - + #if DEBUG void checkrq( run_queue_t rq, - char *msg) + const char *msg) { - register queue_t q1; - register int i, j; - register queue_entry_t e; - register int low; + queue_t q1; + int i, j; + queue_entry_t e; + int low; low = -1; j = 0; @@ -2027,7 +2011,7 @@ void checkrq( else { if (low == -1) low = i; - + for (e = q1->next; e != q1; e = e->next) { j++; if (e->next->prev != e) @@ -2045,10 +2029,10 @@ void checkrq( } void thread_check( - register thread_t th, - register run_queue_t rq) + thread_t th, + run_queue_t rq) { - register unsigned int whichq; + unsigned int whichq; whichq = th->sched_pri; if (whichq >= NRQS) {