Ejemplo n.º 1
0
/*
 * 	Event timer interrupt.
 *
 * XXX a drawback of this implementation is that events serviced earlier must not set deadlines
 *     that occur before the entire chain completes.
 *
 * XXX a better implementation would use a set of generic callouts and iterate over them
 */
void
etimer_intr(
__unused int inuser,
__unused uint64_t iaddr)
{
	uint64_t		abstime;
	rtclock_timer_t		*mytimer;
	struct per_proc_info	*pp;

	pp = getPerProc();

	mytimer = &pp->rtclock_timer;				/* Point to the event timer */

	abstime = mach_absolute_time();				/* Get the time now */

	/* is it time for power management state change? */	
	if (pp->pms.pmsPop <= abstime) {
	        KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 3) | DBG_FUNC_START, 0, 0, 0, 0, 0);
		pmsStep(1);					/* Yes, advance step */
	        KERNEL_DEBUG_CONSTANT(MACHDBG_CODE(DBG_MACH_EXCP_DECI, 3) | DBG_FUNC_END, 0, 0, 0, 0, 0);

		abstime = mach_absolute_time();			/* Get the time again since we ran a bit */
	}

	/* has a pending clock timer expired? */
	if (mytimer->deadline <= abstime) {			/* Have we expired the deadline? */
		mytimer->has_expired = TRUE;			/* Remember that we popped */
		mytimer->deadline = timer_queue_expire(&mytimer->queue, abstime);
		mytimer->has_expired = FALSE;
	}

	/* schedule our next deadline */
	pp->rtcPop = EndOfAllTime;				/* any real deadline will be earlier */
	etimer_resync_deadlines();
}
Ejemplo n.º 2
0
Archivo: etimer.c Proyecto: DiogoPC/xnu
/**
 * etimer_intr
 *
 * Timer interrupt routine, called from the realtime clock interrupt
 * routine.
 */
void etimer_intr(int inuser, uint64_t iaddr)
{
    uint64_t abstime;
    rtclock_timer_t *mytimer;
    cpu_data_t *pp;
    int32_t latency;

    pp = current_cpu_datap();

    SCHED_STATS_TIMER_POP(current_processor());

    abstime = mach_absolute_time(); /* Get the time now */

    /*
     * has a pending clock timer expired? 
     */
    mytimer = &pp->rt_timer;    /* Point to the event timer */
    if (mytimer->deadline <= abstime) {
        mytimer->has_expired = TRUE;    /* Remember that we popped */
        mytimer->deadline = timer_queue_expire(&mytimer->queue, abstime);
        mytimer->has_expired = FALSE;
    }

    pp->rtcPop = EndOfAllTime;  /* any real deadline will be earlier */
    /*
     * schedule our next deadline 
     */

    etimer_resync_deadlines();
}
Ejemplo n.º 3
0
void
timer_queue_expire_local(
    __unused void			*arg)
{
    rtclock_timer_t		*mytimer;
    uint64_t			abstime;
    cpu_data_t			*pp;

    pp = current_cpu_datap();

    mytimer = &pp->rtclock_timer;
    abstime = mach_absolute_time();

    mytimer->has_expired = TRUE;
    mytimer->deadline = timer_queue_expire(&mytimer->queue, abstime);
    mytimer->has_expired = FALSE;
    mytimer->when_set = mach_absolute_time();

    timer_resync_deadlines();
}
Ejemplo n.º 4
0
/*
 * 	Event timer interrupt.
 *
 * XXX a drawback of this implementation is that events serviced earlier must not set deadlines
 *     that occur before the entire chain completes.
 *
 * XXX a better implementation would use a set of generic callouts and iterate over them
 */
void
timer_intr(int		user_mode,
           uint64_t	rip)
{
    uint64_t		abstime;
    rtclock_timer_t		*mytimer;
    cpu_data_t		*pp;
    int64_t			latency;
    uint64_t		pmdeadline;
    boolean_t		timer_processed = FALSE;

    pp = current_cpu_datap();

    SCHED_STATS_TIMER_POP(current_processor());

    abstime = mach_absolute_time();		/* Get the time now */

    /* has a pending clock timer expired? */
    mytimer = &pp->rtclock_timer;		/* Point to the event timer */

    if ((timer_processed = ((mytimer->deadline <= abstime) ||
                            (abstime >= (mytimer->queue.earliest_soft_deadline))))) {
        /*
         * Log interrupt service latency (-ve value expected by tool)
         * a non-PM event is expected next.
         * The requested deadline may be earlier than when it was set
         * - use MAX to avoid reporting bogus latencies.
         */
        latency = (int64_t) (abstime - MAX(mytimer->deadline,
                                           mytimer->when_set));
        /* Log zero timer latencies when opportunistically processing
         * coalesced timers.
         */
        if (latency < 0) {
            TCOAL_DEBUG(0xEEEE0000, abstime, mytimer->queue.earliest_soft_deadline, abstime - mytimer->queue.earliest_soft_deadline, 0, 0);
            latency = 0;
        }

        KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
                                  DECR_TRAP_LATENCY | DBG_FUNC_NONE,
                                  -latency,
                                  ((user_mode != 0) ? rip : VM_KERNEL_UNSLIDE(rip)),
                                  user_mode, 0, 0);

        mytimer->has_expired = TRUE;	/* Remember that we popped */
        mytimer->deadline = timer_queue_expire(&mytimer->queue, abstime);
        mytimer->has_expired = FALSE;

        /* Get the time again since we ran a bit */
        abstime = mach_absolute_time();
        mytimer->when_set = abstime;
    }

    /* is it time for power management state change? */
    if ((pmdeadline = pmCPUGetDeadline(pp)) && (pmdeadline <= abstime)) {
        KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
                                  DECR_PM_DEADLINE | DBG_FUNC_START,
                                  0, 0, 0, 0, 0);
        pmCPUDeadline(pp);
        KERNEL_DEBUG_CONSTANT_IST(KDEBUG_TRACE,
                                  DECR_PM_DEADLINE | DBG_FUNC_END,
                                  0, 0, 0, 0, 0);
        timer_processed = TRUE;
    }

    /* schedule our next deadline */
    x86_lcpu()->rtcDeadline = EndOfAllTime;
    timer_resync_deadlines();

    if (__improbable(timer_processed == FALSE))
        spurious_timers++;
}