#endif
{"unix", unix_start_timer, unix_stop_timer, unix_rearm_timer},
#else
- {"mmtimer", mm_start_timer, mm_stop_timer, NULL},
- {"mmtimer2", mm_start_timer, mm_stop_timer, mm_rearm_timer},
+ {"mmtimer", mm_start_timer, mm_stop_timer, mm_rearm_timer},
{"dynticks", win32_start_timer, win32_stop_timer, win32_rearm_timer},
- {"win32", win32_start_timer, win32_stop_timer, NULL},
#endif
{NULL, }
};
clock = g_malloc0(sizeof(QEMUClock));
clock->type = type;
clock->enabled = 1;
+ clock->last = INT64_MIN;
notifier_list_init(&clock->reset_notifiers);
- /* required to detect & report backward jumps */
- if (type == QEMU_CLOCK_HOST) {
- clock->last = get_clock_realtime();
- }
return clock;
}
void qemu_clock_enable(QEMUClock *clock, int enabled)
{
+ bool old = clock->enabled;
clock->enabled = enabled;
+ if (enabled && !old) {
+ qemu_rearm_alarm_timer(alarm_timer);
+ }
}
int64_t qemu_clock_has_timers(QEMUClock *clock)
/* modify the current timer so that it will be fired when current_time
>= expire_time. The corresponding callback will be called. */
-static void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
+void qemu_mod_timer_ns(QEMUTimer *ts, int64_t expire_time)
{
QEMUTimer **pt, *t;
}
}
-/* modify the current timer so that it will be fired when current_time
- >= expire_time. The corresponding callback will be called. */
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time)
{
qemu_mod_timer_ns(ts, expire_time * ts->scale);
rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
-
- rtc_clock = host_clock;
}
-/* save a timer */
-void qemu_put_timer(QEMUFile *f, QEMUTimer *ts)
+uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts)
{
- uint64_t expire_time;
-
- if (qemu_timer_pending(ts)) {
- expire_time = ts->expire_time;
- } else {
- expire_time = -1;
- }
- qemu_put_be64(f, expire_time);
-}
-
-void qemu_get_timer(QEMUFile *f, QEMUTimer *ts)
-{
- uint64_t expire_time;
-
- expire_time = qemu_get_be64(f);
- if (expire_time != -1) {
- qemu_mod_timer_ns(ts, expire_time);
- } else {
- qemu_del_timer(ts);
- }
+ return qemu_timer_pending(ts) ? ts->expire_time : -1;
}
void qemu_run_all_timers(void)
}
/* vm time timers */
- if (runstate_is_running()) {
- qemu_run_timers(vm_clock);
- }
-
+ qemu_run_timers(vm_clock);
qemu_run_timers(rt_clock);
qemu_run_timers(host_clock);
}
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);
#endif /* _WIN32 */
-static void alarm_timer_on_change_state_rearm(void *opaque, int running,
- RunState state)
+static void quit_timers(void)
{
- if (running)
- qemu_rearm_alarm_timer((struct qemu_alarm_timer *) opaque);
+ struct qemu_alarm_timer *t = alarm_timer;
+ alarm_timer = NULL;
+ t->stop(t);
}
int init_timer_alarm(void)
}
/* first event is at time 0 */
+ atexit(quit_timers);
t->pending = 1;
alarm_timer = t;
- qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t);
return 0;
return err;
}
-void quit_timers(void)
-{
- struct qemu_alarm_timer *t = alarm_timer;
- alarm_timer = NULL;
- t->stop(t);
-}
-
int qemu_calculate_timeout(void)
{
return 1000;