X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0b4e3aa066abc0728aacb4bbeb86f53f9737156e..5eebf7385fedb1517b66b53c28e5aa6bb0a2be50:/osfmk/kern/timer_call.c?ds=sidebyside diff --git a/osfmk/kern/timer_call.c b/osfmk/kern/timer_call.c index 66d69a833..cf5d481f1 100644 --- a/osfmk/kern/timer_call.c +++ b/osfmk/kern/timer_call.c @@ -32,25 +32,30 @@ #include #include +#include #include #include +#ifdef i386 +/* + * Until we arrange for per-cpu timers, use the master cpus queues only. + * Fortunately, the timer_call_lock synchronizes access to all queues. + */ +#undef cpu_number() +#define cpu_number() 0 +#endif /* i386 */ + decl_simple_lock_data(static,timer_call_lock) static queue_head_t - delayed_call_queues[NCPUS]; + timer_call_queues[NCPUS]; static struct { - int pending_num, - pending_hiwat; int delayed_num, delayed_hiwat; -} timer_calls; - -static boolean_t - timer_call_initialized = FALSE; +} timer_call_vars; static void timer_call_interrupt( @@ -65,21 +70,16 @@ timer_call_initialize(void) spl_t s; int i; - if (timer_call_initialized) - panic("timer_call_initialize"); - simple_lock_init(&timer_call_lock, ETAP_MISC_TIMER); s = splclock(); simple_lock(&timer_call_lock); for (i = 0; i < NCPUS; i++) - queue_init(&delayed_call_queues[i]); + queue_init(&timer_call_queues[i]); clock_set_timer_func((clock_timer_func_t)timer_call_interrupt); - timer_call_initialized = TRUE; - simple_unlock(&timer_call_lock); splx(s); } @@ -114,8 +114,8 @@ _delayed_call_enqueue( } insque(qe(call), qe(current)); - if (++timer_calls.delayed_num > timer_calls.delayed_hiwat) - timer_calls.delayed_hiwat = timer_calls.delayed_num; + if (++timer_call_vars.delayed_num > timer_call_vars.delayed_hiwat) + timer_call_vars.delayed_hiwat = timer_call_vars.delayed_num; call->state = DELAYED; } @@ -126,31 +126,7 @@ _delayed_call_dequeue( timer_call_t call) { (void)remque(qe(call)); - timer_calls.delayed_num--; - - call->state = IDLE; -} - -static __inline__ -void -_pending_call_enqueue( - queue_t queue, - timer_call_t call) -{ - enqueue_tail(queue, qe(call)); - if (++timer_calls.pending_num > timer_calls.pending_hiwat) - timer_calls.pending_hiwat = timer_calls.pending_num; - - call->state = PENDING; -} - -static __inline__ -void -_pending_call_dequeue( - timer_call_t call) -{ - (void)remque(qe(call)); - timer_calls.pending_num--; + timer_call_vars.delayed_num--; call->state = IDLE; } @@ -169,27 +145,25 @@ timer_call_enter( uint64_t deadline) { boolean_t result = TRUE; - queue_t delayed; + queue_t queue; spl_t s; s = splclock(); simple_lock(&timer_call_lock); - if (call->state == PENDING) - _pending_call_dequeue(call); - else if (call->state == DELAYED) + if (call->state == DELAYED) _delayed_call_dequeue(call); - else if (call->state == IDLE) + else result = FALSE; call->param1 = 0; call->deadline = deadline; - delayed = &delayed_call_queues[cpu_number()]; + queue = &timer_call_queues[cpu_number()]; - _delayed_call_enqueue(delayed, call); + _delayed_call_enqueue(queue, call); - if (queue_first(delayed) == qe(call)) + if (queue_first(queue) == qe(call)) _set_delayed_call_timer(call); simple_unlock(&timer_call_lock); @@ -205,27 +179,25 @@ timer_call_enter1( uint64_t deadline) { boolean_t result = TRUE; - queue_t delayed; + queue_t queue; spl_t s; s = splclock(); simple_lock(&timer_call_lock); - if (call->state == PENDING) - _pending_call_dequeue(call); - else if (call->state == DELAYED) + if (call->state == DELAYED) _delayed_call_dequeue(call); - else if (call->state == IDLE) + else result = FALSE; call->param1 = param1; call->deadline = deadline; - delayed = &delayed_call_queues[cpu_number()]; + queue = &timer_call_queues[cpu_number()]; - _delayed_call_enqueue(delayed, call); + _delayed_call_enqueue(queue, call); - if (queue_first(delayed) == qe(call)) + if (queue_first(queue) == qe(call)) _set_delayed_call_timer(call); simple_unlock(&timer_call_lock); @@ -244,9 +216,7 @@ timer_call_cancel( s = splclock(); simple_lock(&timer_call_lock); - if (call->state == PENDING) - _pending_call_dequeue(call); - else if (call->state == DELAYED) + if (call->state == DELAYED) _delayed_call_dequeue(call); else result = FALSE; @@ -280,19 +250,55 @@ timer_call_is_delayed( return (result); } +/* + * Called at splclock. + */ + +void +timer_call_shutdown( + processor_t processor) +{ + timer_call_t call; + queue_t queue, myqueue; + + assert(processor != current_processor()); + + queue = &timer_call_queues[processor->slot_num]; + myqueue = &timer_call_queues[cpu_number()]; + + simple_lock(&timer_call_lock); + + call = TC(queue_first(queue)); + + while (!queue_end(queue, qe(call))) { + _delayed_call_dequeue(call); + + _delayed_call_enqueue(myqueue, call); + + call = TC(queue_first(queue)); + } + + call = TC(queue_first(myqueue)); + + if (!queue_end(myqueue, qe(call))) + _set_delayed_call_timer(call); + + simple_unlock(&timer_call_lock); +} + static void timer_call_interrupt( uint64_t timestamp) { timer_call_t call; - queue_t delayed = &delayed_call_queues[cpu_number()]; + queue_t queue = &timer_call_queues[cpu_number()]; simple_lock(&timer_call_lock); - call = TC(queue_first(delayed)); + call = TC(queue_first(queue)); - while (!queue_end(delayed, qe(call))) { + while (!queue_end(queue, qe(call))) { if (call->deadline <= timestamp) { timer_call_func_t func; timer_call_param_t param0, param1; @@ -312,10 +318,10 @@ timer_call_interrupt( else break; - call = TC(queue_first(delayed)); + call = TC(queue_first(queue)); } - if (!queue_end(delayed, qe(call))) + if (!queue_end(queue, qe(call))) _set_delayed_call_timer(call); simple_unlock(&timer_call_lock);