Пример #1
0
static void ptimer_tick(void *opaque)
{
    ptimer_state *s = (ptimer_state *)opaque;
    ptimer_trigger(s);
    s->delta = 0;
    if (s->enabled == 2) {
        s->enabled = 0;
    } else {
        ptimer_reload(s);
    }
}
Пример #2
0
static void ptimer_reload(ptimer_state *s)
{
    if (s->delta == 0) {
        ptimer_trigger(s);
        s->delta = s->limit;
    }
    if (s->delta == 0 || s->period == 0) {
        fprintf(stderr, "Timer with period zero, disabling\n");
        s->enabled = 0;
        return;
    }

    s->last_event = s->next_event;
    s->next_event = s->last_event + s->delta * s->period;
    if (s->period_frac) {
        s->next_event += ((int64_t)s->period_frac * s->delta) >> 32;
    }
Пример #3
0
static void ptimer_reload(ptimer_state *s)
{
    uint32_t period_frac = s->period_frac;
    uint64_t period = s->period;

    if (s->delta == 0) {
        ptimer_trigger(s);
        s->delta = s->limit;
    }
    if (s->delta == 0 || s->period == 0) {
        fprintf(stderr, "Timer with period zero, disabling\n");
        s->enabled = 0;
        return;
    }

    /*
     * Artificially limit timeout rate to something
     * achievable under QEMU.  Otherwise, QEMU spends all
     * its time generating timer interrupts, and there
     * is no forward progress.
     * About ten microseconds is the fastest that really works
     * on the current generation of host machines.
     */

    if (s->enabled == 1 && (s->delta * period < 10000) && !use_icount) {
        period = 10000 / s->delta;
        period_frac = 0;
    }

    s->last_event = s->next_event;
    s->next_event = s->last_event + s->delta * period;
    if (period_frac) {
        s->next_event += ((int64_t)period_frac * s->delta) >> 32;
    }
    timer_mod(s->timer, s->next_event);
}