*/
#include "qemu/osdep.h"
-#include "qemu-common.h"
#include "qemu/cutils.h"
#include "migration/vmstate.h"
#include "qapi/error.h"
static int64_t icount_get_executed(CPUState *cpu)
{
return (cpu->icount_budget -
- (cpu_neg(cpu)->icount_decr.u16.low + cpu->icount_extra));
+ (cpu->neg.icount_decr.u16.low + cpu->icount_extra));
}
/*
CPUState *cpu = current_cpu;
if (cpu && cpu->running) {
- if (!cpu->can_do_io) {
+ if (!cpu->neg.can_do_io) {
error_report("Bad icount read");
exit(1);
}
int64_t cur_icount;
int64_t delta;
- /* Protected by TimersState mutex. */
- static int64_t last_delta;
-
/* If the VM is not running, then do nothing. */
if (!runstate_is_running()) {
return;
delta = cur_icount - cur_time;
/* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */
if (delta > 0
- && last_delta + ICOUNT_WOBBLE < delta * 2
+ && timers_state.last_delta + ICOUNT_WOBBLE < delta * 2
&& timers_state.icount_time_shift > 0) {
/* The guest is getting too far ahead. Slow time down. */
qatomic_set(&timers_state.icount_time_shift,
timers_state.icount_time_shift - 1);
}
if (delta < 0
- && last_delta - ICOUNT_WOBBLE > delta * 2
+ && timers_state.last_delta - ICOUNT_WOBBLE > delta * 2
&& timers_state.icount_time_shift < MAX_ICOUNT_SHIFT) {
/* The guest is getting too far behind. Speed time up. */
qatomic_set(&timers_state.icount_time_shift,
timers_state.icount_time_shift + 1);
}
- last_delta = delta;
+ timers_state.last_delta = delta;
qatomic_set_i64(&timers_state.qemu_icount_bias,
cur_icount - (timers_state.qemu_icount
<< timers_state.icount_time_shift));
warp_delta = clock - timers_state.vm_clock_warp_start;
if (icount_enabled() == 2) {
/*
- * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too
- * far ahead of real time.
+ * In adaptive mode, do not let QEMU_CLOCK_VIRTUAL run too far
+ * ahead of real time (it might already be ahead so careful not
+ * to go backwards).
*/
int64_t cur_icount = icount_get_locked();
int64_t delta = clock - cur_icount;
+
+ if (delta < 0) {
+ delta = 0;
+ }
warp_delta = MIN(warp_delta, delta);
}
qatomic_set_i64(&timers_state.qemu_icount_bias,
* vCPU is sleeping and warp can't be started.
* It is probably a race condition: notification sent
* to vCPU was processed in advance and vCPU went to sleep.
- * Therefore we have to wake it up for doing someting.
+ * Therefore we have to wake it up for doing something.
*/
- if (replay_has_checkpoint()) {
+ if (replay_has_event()) {
qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
}
return;
return;
}
+ replay_async_events();
+
/* warp clock deterministically in record/replay mode */
if (!replay_checkpoint(CHECKPOINT_CLOCK_WARP_ACCOUNT)) {
return;
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
NANOSECONDS_PER_SECOND / 10);
}
+
+void icount_notify_exit(void)
+{
+ if (icount_enabled() && current_cpu) {
+ qemu_cpu_kick(current_cpu);
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+ }
+}