/* * thread_call_func_delayed: * * Enqueue a function callout to * occur at the stated time. */ void thread_call_func_delayed( thread_call_func_t func, thread_call_param_t param, uint64_t deadline) { thread_call_t call; thread_call_group_t group = &thread_call_groups[THREAD_CALL_PRIORITY_HIGH]; spl_t s; s = splsched(); thread_call_lock_spin(); call = _internal_call_allocate(); call->tc_call.func = func; call->tc_call.param0 = param; call->tc_call.param1 = 0; _delayed_call_enqueue(call, group, deadline); if (queue_first(&group->delayed_queue) == qe(call)) _set_delayed_call_timer(call, group); thread_call_unlock(); splx(s); }
boolean_t thread_call_enter1_delayed( thread_call_t call, thread_call_param_t param1, uint64_t deadline) { boolean_t result = TRUE; thread_call_group_t group; spl_t s; group = thread_call_get_group(call); s = splsched(); thread_call_lock_spin(); result = _delayed_call_enqueue(call, group, deadline); if (queue_first(&group->delayed_queue) == qe(call)) _set_delayed_call_timer(call, group); call->tc_call.param1 = param1; thread_call_unlock(); splx(s); return (result); }
void timer_call_shutdown( processor_t processor) { timer_call_t call; queue_t queue, myqueue; assert(processor != current_processor()); queue = &PROCESSOR_DATA(processor, timer_call_queue); myqueue = &PROCESSOR_DATA(current_processor(), timer_call_queue); 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); }
void thread_call_delayed_timer( timer_call_param_t p0, __unused timer_call_param_t p1 ) { thread_call_t call; thread_call_group_t group = p0; uint64_t timestamp; thread_call_lock_spin(); timestamp = mach_absolute_time(); call = TC(queue_first(&group->delayed_queue)); while (!queue_end(&group->delayed_queue, qe(call))) { if (call->tc_call.deadline <= timestamp) { _pending_call_enqueue(call, group); } else break; call = TC(queue_first(&group->delayed_queue)); } if (!queue_end(&group->delayed_queue, qe(call))) _set_delayed_call_timer(call, group); thread_call_unlock(); }
boolean_t timer_call_cancel( timer_call_t call) { boolean_t result = TRUE; spl_t s; s = splclock(); simple_lock(&timer_call_lock); if (call->state == DELAYED) { queue_t queue = &PROCESSOR_DATA(current_processor(), timer_call_queue); if (queue_first(queue) == qe(call)) { _delayed_call_dequeue(call); if (!queue_empty(queue)) _set_delayed_call_timer((timer_call_t)queue_first(queue)); } else _delayed_call_dequeue(call); } else result = FALSE; simple_unlock(&timer_call_lock); splx(s); return (result); }
boolean_t timer_call_enter1( timer_call_t call, timer_call_param_t param1, uint64_t deadline) { boolean_t result = TRUE; queue_t queue; spl_t s; s = splclock(); simple_lock(&timer_call_lock); if (call->state == DELAYED) _delayed_call_dequeue(call); else result = FALSE; call->param1 = param1; call->deadline = deadline; queue = &PROCESSOR_DATA(current_processor(), timer_call_queue); _delayed_call_enqueue(queue, call); if (queue_first(queue) == qe(call)) _set_delayed_call_timer(call); simple_unlock(&timer_call_lock); splx(s); return (result); }
void thread_call_delayed_timer( timer_call_param_t p0, __unused timer_call_param_t p1 ) { thread_call_t call; thread_call_group_t group = p0; boolean_t new_pending = FALSE; uint64_t timestamp; thread_call_lock_spin(); timestamp = mach_absolute_time(); call = TC(queue_first(&group->delayed_queue)); while (!queue_end(&group->delayed_queue, qe(call))) { if (call->deadline <= timestamp) { _pending_call_enqueue(call, group); new_pending = TRUE; } else break; call = TC(queue_first(&group->delayed_queue)); } if (!queue_end(&group->delayed_queue, qe(call))) _set_delayed_call_timer(call, group); if (new_pending && group->active_count == 0) thread_call_wake(group); thread_call_unlock(); }
/* * thread_call_enter_delayed: * * Enqueue a callout entry to occur * at the stated time. * * Returns TRUE if the call was * already on a queue. */ boolean_t thread_call_enter_delayed( thread_call_t call, uint64_t deadline) { boolean_t result = TRUE; thread_call_group_t group = &thread_call_group0; spl_t s; s = splsched(); thread_call_lock_spin(); result = _delayed_call_enqueue(call, group, deadline); if (queue_first(&group->delayed_queue) == qe(call)) _set_delayed_call_timer(call, group); call->param1 = 0; thread_call_unlock(); splx(s); return (result); }
static void timer_call_interrupt(uint64_t timestamp) { timer_call_t call; queue_t queue; simple_lock(&timer_call_lock); queue = &PROCESSOR_DATA(current_processor(), timer_call_queue); call = TC(queue_first(queue)); while (!queue_end(queue, qe(call))) { if (call->deadline <= timestamp) { timer_call_func_t func; timer_call_param_t param0, param1; _delayed_call_dequeue(call); func = call->func; param0 = call->param0; param1 = call->param1; simple_unlock(&timer_call_lock); KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 2) | DBG_FUNC_START, (unsigned int)func, (unsigned int)param0, (unsigned int)param1, 0, 0); #if CONFIG_DTRACE && (DEVELOPMENT || DEBUG ) DTRACE_TMR3(callout__start, timer_call_func_t, func, timer_call_param_t, param0, timer_call_param_t, param1); #endif (*func)(param0, param1); #if CONFIG_DTRACE && (DEVELOPMENT || DEBUG ) DTRACE_TMR3(callout__end, timer_call_func_t, func, timer_call_param_t, param0, timer_call_param_t, param1); #endif KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 2) | DBG_FUNC_END, (unsigned int)func, (unsigned int)param0, (unsigned int)param1, 0, 0); simple_lock(&timer_call_lock); } else break; call = TC(queue_first(queue)); } if (!queue_end(queue, qe(call))) _set_delayed_call_timer(call); simple_unlock(&timer_call_lock); }