__private_extern__ void devtimer_set_absolute(devtimer_ref timer, struct timeval abs_time, devtimer_timeout_func timeout_func, void * arg1, void * arg2) { if (timer->dt_callout == NULL) { printf("devtimer_set_absolute: uninitialized/freed timer\n"); return; } devtimer_cancel(timer); if (timeout_func == NULL) { return; } timer->dt_timeout_func = timeout_func; timer->dt_arg1 = arg1; timer->dt_arg2 = arg2; _devtimer_printf("devtimer: wakeup time is (%d.%d)\n", abs_time.tv_sec, abs_time.tv_usec); timer->dt_generation++; devtimer_retain(timer); thread_call_enter1_delayed(timer->dt_callout, &timer->dt_generation, timeval_to_absolutetime(abs_time)); return; }
cyclic_id_t cyclic_add(cyc_handler_t *handler, cyc_time_t *when) { uint64_t now; wrap_thread_call_t *wrapTC = _MALLOC(sizeof(wrap_thread_call_t), M_TEMP, M_ZERO | M_WAITOK); if (NULL == wrapTC) return CYCLIC_NONE; wrapTC->TChdl = thread_call_allocate( _cyclic_apply, NULL ); wrapTC->hdlr = *handler; wrapTC->when = *when; ASSERT(when->cyt_when == 0); ASSERT(when->cyt_interval < WAKEUP_REAPER); nanoseconds_to_absolutetime(wrapTC->when.cyt_interval, (uint64_t *)&wrapTC->when.cyt_interval); now = mach_absolute_time(); wrapTC->deadline = now; clock_deadline_for_periodic_event( wrapTC->when.cyt_interval, now, &(wrapTC->deadline) ); (void)thread_call_enter1_delayed( wrapTC->TChdl, (void *)wrapTC, wrapTC->deadline ); return (cyclic_id_t)wrapTC; }
__private_extern__ kern_return_t chudxnu_timer_callback_enter( chud_timer_t timer, uint32_t param1, uint32_t time, uint32_t units) { uint64_t t_delay; clock_interval_to_deadline(time, units, &t_delay); thread_call_enter1_delayed((thread_call_t)timer, (thread_call_param_t)param1, t_delay); return KERN_SUCCESS; }
/* * _cyclic_apply will run on some thread under kernel_task. That's OK for the * cleaner and the deadman, but too distant in time and place for the profile provider. */ static void _cyclic_apply( void *ignore, void *vTChdl ) { #pragma unused(ignore) wrap_thread_call_t *wrapTC = (wrap_thread_call_t *)vTChdl; (*(wrapTC->hdlr.cyh_func))( wrapTC->hdlr.cyh_arg ); clock_deadline_for_periodic_event( wrapTC->when.cyt_interval, mach_absolute_time(), &(wrapTC->deadline) ); (void)thread_call_enter1_delayed( wrapTC->TChdl, (void *)wrapTC, wrapTC->deadline ); /* Did cyclic_remove request a wakeup call when this thread call was re-armed? */ if (wrapTC->when.cyt_interval == WAKEUP_REAPER) thread_wakeup((event_t)wrapTC); }
void darwin_iwi3945::queue_te(int num, thread_call_func_t func, thread_call_param_t par, UInt32 timei, bool start) { if (tlink[num]) queue_td(num,NULL); //IWI_DEBUG("queue_te0 %d\n",tlink[num]); if (!tlink[num]) tlink[num]=thread_call_allocate(func,this); //IWI_DEBUG("queue_te1 %d\n",tlink[num]); uint64_t timei2; if (timei) clock_interval_to_deadline(timei,kMillisecondScale,&timei2); //IWI_DEBUG("queue_te time %d %d\n",timei,timei2); int r; if (start==true && tlink[num]) { if (!par && !timei) r=thread_call_enter(tlink[num]); if (!par && timei) r=thread_call_enter_delayed(tlink[num],timei2); if (par && !timei) r=thread_call_enter1(tlink[num],par); if (par && timei) r=thread_call_enter1_delayed(tlink[num],par,timei2); } //IWI_DEBUG("queue_te result %d\n",r); }
int PEHaltRestart(unsigned int type) { IOPMrootDomain *pmRootDomain = IOService::getPMRootDomain(); bool noWaitForResponses; AbsoluteTime deadline; thread_call_t shutdown_hang; if(type == kPEHaltCPU || type == kPERestartCPU) { /* Notify IOKit PM clients of shutdown/restart Clients subscribe to this message with a call to IOService::registerInterest() */ /* Spawn a thread that will panic in 30 seconds. If all goes well the machine will be off by the time the timer expires. */ shutdown_hang = thread_call_allocate( &IOPMPanicOnShutdownHang, (thread_call_param_t) type); clock_interval_to_deadline( 30, kSecondScale, &deadline ); thread_call_enter1_delayed( shutdown_hang, 0, deadline ); noWaitForResponses = pmRootDomain->tellChangeDown2(type); /* This notification should have few clients who all do their work synchronously. In this "shutdown notification" context we don't give drivers the option of working asynchronously and responding later. PM internals make it very hard to wait for asynchronous replies. In fact, it's a bad idea to even be calling tellChangeDown2 from here at all. */ } if (gIOPlatform) return gIOPlatform->haltRestart(type); else return -1; }