static void unix_rearm_timer(struct qemu_alarm_timer *t) { struct itimerval itv; int64_t nearest_delta_ns = INT64_MAX; int err; assert(alarm_has_dynticks(t)); if (!active_timers[QEMU_CLOCK_REALTIME] && !active_timers[QEMU_CLOCK_VIRTUAL] && !active_timers[QEMU_CLOCK_HOST]) return; nearest_delta_ns = qemu_next_alarm_deadline(); if (nearest_delta_ns < MIN_TIMER_REARM_NS) nearest_delta_ns = MIN_TIMER_REARM_NS; itv.it_interval.tv_sec = 0; itv.it_interval.tv_usec = 0; /* 0 for one-shot timer */ itv.it_value.tv_sec = nearest_delta_ns / 1000000000; itv.it_value.tv_usec = (nearest_delta_ns % 1000000000) / 1000; err = setitimer(ITIMER_REAL, &itv, NULL); if (err) { perror("setitimer"); fprintf(stderr, "Internal timer error: aborting\n"); exit(1); } }
static void mm_rearm_timer(struct qemu_alarm_timer *t) { int nearest_delta_ms; assert(alarm_has_dynticks(t)); if (!active_timers[QEMU_CLOCK_REALTIME] && !active_timers[QEMU_CLOCK_VIRTUAL] && !active_timers[QEMU_CLOCK_HOST]) { return; } timeKillEvent(mm_timer); nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000; if (nearest_delta_ms < 1) { nearest_delta_ms = 1; } mm_timer = timeSetEvent(nearest_delta_ms, mm_period, mm_alarm_handler, (DWORD_PTR)t, TIME_ONESHOT | TIME_CALLBACK_FUNCTION); if (!mm_timer) { fprintf(stderr, "Failed to re-arm win32 alarm timer %ld\n", GetLastError()); timeEndPeriod(mm_period); exit(1); } }
static void win32_rearm_timer(struct qemu_alarm_timer *t) { HANDLE hTimer = t->timer; int nearest_delta_ms; BOOLEAN success; assert(alarm_has_dynticks(t)); if (!active_timers[QEMU_CLOCK_REALTIME] && !active_timers[QEMU_CLOCK_VIRTUAL] && !active_timers[QEMU_CLOCK_HOST]) return; nearest_delta_ms = (qemu_next_alarm_deadline() + 999999) / 1000000; if (nearest_delta_ms < 1) { nearest_delta_ms = 1; } success = ChangeTimerQueueTimer(NULL, hTimer, nearest_delta_ms, 3600000); if (!success) { fprintf(stderr, "Failed to rearm win32 alarm timer: %ld\n", GetLastError()); exit(-1); } }
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) { int64_t nearest_delta_ns = qemu_next_alarm_deadline(); if (nearest_delta_ns < INT64_MAX) { t->rearm(t, nearest_delta_ns); } }
static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) { int64_t nearest_delta_ns; if (!rt_clock->active_timers && !vm_clock->active_timers && !host_clock->active_timers) { return; } nearest_delta_ns = qemu_next_alarm_deadline(); t->rearm(t, nearest_delta_ns); }
static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { struct qemu_alarm_timer *t = alarm_timer; if (!t) { return; } if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) { t->expired = alarm_has_dynticks(t); t->pending = 1; qemu_notify_event(); } }
static void host_alarm_handler(int host_signum) #endif { struct qemu_alarm_timer *t = alarm_timer; if (!t) return; if (alarm_has_dynticks(t) || qemu_next_alarm_deadline () <= 0) { t->expired = alarm_has_dynticks(t); t->pending = 1; qemu_notify_event(); } }
static void CALLBACK mm_alarm_handler(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, DWORD_PTR dw2) { struct qemu_alarm_timer *t = alarm_timer; if (!t) { return; } // We can actually call qemu_next_alarm_deadline() here since this // doesn't run in a signal handler, but a different thread. if (alarm_has_dynticks(t) || qemu_next_alarm_deadline() <= 0) { t->expired = 1; timer_alarm_pending = 1; qemu_notify_event(); } }
static void tlm_rearm_timer(struct qemu_alarm_timer *t) { int64_t nearest_delta_ns = INT64_MAX; if (!active_timers[QEMU_CLOCK_REALTIME] && !active_timers[QEMU_CLOCK_VIRTUAL] && !active_timers[QEMU_CLOCK_HOST]) return; nearest_delta_ns = qemu_next_alarm_deadline(); if (nearest_delta_ns < MIN_TIMER_REARM_NS) nearest_delta_ns = MIN_TIMER_REARM_NS; if (tlm_timer_start) { tlm_timer_start(tlm_timer_opaque, NULL, tlm_timer_handler, nearest_delta_ns); } }
static void host_alarm_handler(int host_signum) #endif { struct qemu_alarm_timer *t = alarm_timer; if (!t) return; #if 0 #define DISP_FREQ 1000 { static int64_t delta_min = INT64_MAX; static int64_t delta_max, delta_cum, last_clock, delta, ti; static int count; ti = qemu_get_clock_ns(vm_clock); if (last_clock != 0) { delta = ti - last_clock; if (delta < delta_min) delta_min = delta; if (delta > delta_max) delta_max = delta; delta_cum += delta; if (++count == DISP_FREQ) { printf("timer: min=%" PRId64 " us max=%" PRId64 " us avg=%" PRId64 " us avg_freq=%0.3f Hz\n", muldiv64(delta_min, 1000000, get_ticks_per_sec()), muldiv64(delta_max, 1000000, get_ticks_per_sec()), muldiv64(delta_cum, 1000000 / DISP_FREQ, get_ticks_per_sec()), (double)get_ticks_per_sec() / ((double)delta_cum / DISP_FREQ)); count = 0; delta_min = INT64_MAX; delta_max = 0; delta_cum = 0; } } last_clock = ti; } #endif if (alarm_has_dynticks(t) || qemu_next_alarm_deadline () <= 0) { t->expired = alarm_has_dynticks(t); t->pending = 1; qemu_notify_event(); } }
static void dynticks_rearm_timer(struct qemu_alarm_timer *t) { timer_t host_timer = t->timer; struct itimerspec timeout; int64_t nearest_delta_ns = INT64_MAX; int64_t current_ns; assert(alarm_has_dynticks(t)); if (!active_timers[QEMU_CLOCK_REALTIME] && !active_timers[QEMU_CLOCK_VIRTUAL] && !active_timers[QEMU_CLOCK_HOST]) return; nearest_delta_ns = qemu_next_alarm_deadline(); if (nearest_delta_ns < MIN_TIMER_REARM_NS) nearest_delta_ns = MIN_TIMER_REARM_NS; /* check whether a timer is already running */ if (timer_gettime(host_timer, &timeout)) { perror("gettime"); fprintf(stderr, "Internal timer error: aborting\n"); exit(1); } current_ns = timeout.it_value.tv_sec * 1000000000LL + timeout.it_value.tv_nsec; if (current_ns && current_ns <= nearest_delta_ns) return; timeout.it_interval.tv_sec = 0; timeout.it_interval.tv_nsec = 0; /* 0 for one-shot timer */ timeout.it_value.tv_sec = nearest_delta_ns / 1000000000; timeout.it_value.tv_nsec = nearest_delta_ns % 1000000000; if (timer_settime(host_timer, 0 /* RELATIVE */, &timeout, NULL)) { perror("settime"); fprintf(stderr, "Internal timer error: aborting\n"); exit(1); } }