|
@@ -25,6 +25,7 @@
|
|
#include "qemu/main-loop.h"
|
|
#include "qemu/main-loop.h"
|
|
#include "qemu/timer.h"
|
|
#include "qemu/timer.h"
|
|
#include "sysemu/replay.h"
|
|
#include "sysemu/replay.h"
|
|
|
|
+#include "sysemu/sysemu.h"
|
|
|
|
|
|
#ifdef CONFIG_POSIX
|
|
#ifdef CONFIG_POSIX
|
|
#include <pthread.h>
|
|
#include <pthread.h>
|
|
@@ -478,10 +479,31 @@ bool timerlist_run_timers(QEMUTimerList *timer_list)
|
|
void *opaque;
|
|
void *opaque;
|
|
|
|
|
|
qemu_event_reset(&timer_list->timers_done_ev);
|
|
qemu_event_reset(&timer_list->timers_done_ev);
|
|
- if (!timer_list->clock->enabled) {
|
|
|
|
|
|
+ if (!timer_list->clock->enabled || !timer_list->active_timers) {
|
|
goto out;
|
|
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);
|
|
current_time = qemu_clock_get_ns(timer_list->clock->type);
|
|
for(;;) {
|
|
for(;;) {
|
|
qemu_mutex_lock(&timer_list->active_timers_lock);
|
|
qemu_mutex_lock(&timer_list->active_timers_lock);
|
|
@@ -545,11 +567,17 @@ int64_t timerlistgroup_deadline_ns(QEMUTimerListGroup *tlg)
|
|
{
|
|
{
|
|
int64_t deadline = -1;
|
|
int64_t deadline = -1;
|
|
QEMUClockType type;
|
|
QEMUClockType type;
|
|
|
|
+ bool play = replay_mode == REPLAY_MODE_PLAY;
|
|
for (type = 0; type < QEMU_CLOCK_MAX; type++) {
|
|
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;
|
|
return deadline;
|
|
@@ -574,8 +602,7 @@ int64_t qemu_clock_get_ns(QEMUClockType type)
|
|
now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime());
|
|
now = REPLAY_CLOCK(REPLAY_CLOCK_HOST, get_clock_realtime());
|
|
last = clock->last;
|
|
last = clock->last;
|
|
clock->last = now;
|
|
clock->last = now;
|
|
- if ((now < last || now > (last + get_max_clock_jump()))
|
|
|
|
- && replay_mode == REPLAY_MODE_NONE) {
|
|
|
|
|
|
+ if (now < last || now > (last + get_max_clock_jump())) {
|
|
notifier_list_notify(&clock->reset_notifiers, &now);
|
|
notifier_list_notify(&clock->reset_notifiers, &now);
|
|
}
|
|
}
|
|
return now;
|
|
return now;
|