示例#1
0
__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;
}
示例#2
0
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;
}
示例#4
0
/*
 * _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);
}
示例#5
0
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;
}