diff options
Diffstat (limited to 'qemu/qemu-timer.c')
-rw-r--r-- | qemu/qemu-timer.c | 48 |
1 files changed, 40 insertions, 8 deletions
diff --git a/qemu/qemu-timer.c b/qemu/qemu-timer.c index 2463fe6f6..4441fe66f 100644 --- a/qemu/qemu-timer.c +++ b/qemu/qemu-timer.c @@ -22,8 +22,11 @@ * THE SOFTWARE. */ +#include "qemu/osdep.h" #include "qemu/main-loop.h" #include "qemu/timer.h" +#include "sysemu/replay.h" +#include "sysemu/sysemu.h" #ifdef CONFIG_POSIX #include <pthread.h> @@ -391,7 +394,9 @@ static bool timer_mod_ns_locked(QEMUTimerList *timer_list, static void timerlist_rearm(QEMUTimerList *timer_list) { /* Interrupt execution to force deadline recalculation. */ - qemu_clock_warp(timer_list->clock->type); + if (timer_list->clock->type == QEMU_CLOCK_VIRTUAL) { + qemu_start_warp_timer(); + } timerlist_notify(timer_list); } @@ -477,10 +482,31 @@ bool timerlist_run_timers(QEMUTimerList *timer_list) void *opaque; qemu_event_reset(&timer_list->timers_done_ev); - if (!timer_list->clock->enabled) { + if (!timer_list->clock->enabled || !timer_list->active_timers) { goto out; } + switch (timer_list->clock->type) { + case QEMU_CLOCK_REALTIME: + break; + default: + case QEMU_CLOCK_VIRTUAL: + if (!replay_checkpoint(CHECKPOINT_CLOCK_VIRTUAL)) { + goto out; + } + break; + case QEMU_CLOCK_HOST: + if (!replay_checkpoint(CHECKPOINT_CLOCK_HOST)) { + goto out; + } + break; + case QEMU_CLOCK_VIRTUAL_RT: + if (!replay_checkpoint(CHECKPOINT_CLOCK_VIRTUAL_RT)) { + goto out; + } + break; + } + current_time = qemu_clock_get_ns(timer_list->clock->type); for(;;) { qemu_mutex_lock(&timer_list->active_timers_lock); @@ -544,11 +570,17 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg) { int64_t deadline = -1; QEMUClockType type; + bool play = replay_mode == REPLAY_MODE_PLAY; for (type = 0; type < QEMU_CLOCK_MAX; type++) { - if (qemu_clock_use_for_deadline(tlg->tl[type]->clock->type)) { - deadline = qemu_soonest_timeout(deadline, - timerlist_deadline_ns( - tlg->tl[type])); + if (qemu_clock_use_for_deadline(type)) { + if (!play || type == QEMU_CLOCK_REALTIME) { + deadline = qemu_soonest_timeout(deadline, + timerlist_deadline_ns(tlg->tl[type])); + } else { + /* Read clock from the replay file and + do not calculate the deadline, based on virtual clock. */ + qemu_clock_get_ns(type); + } } } return deadline; @@ -570,7 +602,7 @@ int64_t qemu_clock_get_ns(QEMUClockType type) return cpu_get_clock(); } case QEMU_CLOCK_HOST: - now = get_clock_realtime(); + now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime()); last = clock->last; clock->last = now; if (now < last || now > (last + get_max_clock_jump())) { @@ -578,7 +610,7 @@ int64_t qemu_clock_get_ns(QEMUClockType type) } return now; case QEMU_CLOCK_VIRTUAL_RT: - return cpu_get_clock(); + return REPLAY_CLOCK(REPLAY_CLOCK_VIRTUAL_RT, cpu_get_clock()); } } |