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); } }
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; }
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); }