@@ -319,8 +319,10 @@ static int64_t qemu_icount_round(int64_t count)
return (count + (1 << icount_time_shift) - 1) >> icount_time_shift;
}
-static void icount_warp_rt(void *opaque)
+void icount_warp_rt(void *opaque)
{
+ int64_t next_vm_deadline = -1;
+
/* The icount_warp_timer is rescheduled soon after vm_clock_warp_start
* changes from -1 to another value, so the race here is okay.
*/
@@ -328,6 +330,13 @@ static void icount_warp_rt(void *opaque)
return;
}
+ if (cexe_is_enabled()) {
+ /*
+ * We need this because the standard warp_delta is not deterministic.
+ */
+ next_vm_deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+ }
+
seqlock_write_lock(&timers_state.vm_clock_seqlock);
if (runstate_is_running()) {
int64_t clock = qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
@@ -344,7 +353,13 @@ static void icount_warp_rt(void *opaque)
int64_t delta = cur_time - cur_icount;
warp_delta = MIN(warp_delta, delta);
}
- timers_state.qemu_icount_bias += warp_delta;
+ if (cexe_is_enabled()) {
+ if (next_vm_deadline > 0) {
+ timers_state.qemu_icount_bias += next_vm_deadline;
+ }
+ } else {
+ timers_state.qemu_icount_bias += warp_delta;
+ }
}
vm_clock_warp_start = -1;
seqlock_write_unlock(&timers_state.vm_clock_seqlock);
@@ -754,6 +754,14 @@ int64_t cpu_get_icount(int with_bias);
int64_t cpu_get_clock(void);
int64_t cpu_icount_to_ns(int64_t icount);
+/**
+ * void icount_warp_rt:
+ *
+ * Move icount to the realtime clock or to the next QEMU_VIRTUAL_CLOCK event
+ * when reverse execution is enabled.
+ */
+void icount_warp_rt(void *opaque);
+
/*******************************************/
/* host CPU ticks (if available) */
@@ -25,6 +25,8 @@
#ifndef REVERSE_EXECUTION
#define REVERSE_EXECUTION
+#include "qom/cpu.h"
+
void cexe_setup(void);
void cexe_step_backward(CPUState *cpu, uint64_t steps);
void cexe_stop_stepping_back_mode(void);
@@ -34,6 +34,8 @@
#include "qemu/compatfd.h"
+#include "reverse-execution.h"
+
/* If we have signalfd, we mask out the signals we want to handle and then
* use signalfd to listen for them. We rely on whatever the current signal
* handler is to dispatch the signals when we receive them.
@@ -489,6 +491,14 @@ int main_loop_wait(int nonblocking)
qemu_clock_run_all_timers();
+ /*
+ * Sometimes deadlock can appears because there is no pending event on
+ * virtual clock.
+ */
+ if (cexe_is_enabled()) {
+ icount_warp_rt(NULL);
+ }
+
return ret;
}
@@ -30,3 +30,4 @@ stub-obj-y += vmstate.o
stub-obj-$(CONFIG_WIN32) += fd-register.o
stub-obj-y += cpus.o
stub-obj-y += kvm.o
+stub-obj-y += cexe-stub.o
new file mode 100644
@@ -0,0 +1,32 @@
+/*
+ * cexe-stub.c
+ *
+ * Copyright (C) 2014 : GreenSocs Ltd
+ * http://www.greensocs.com/ , email: info@greensocs.com
+ *
+ * Developed by :
+ * Frederic Konrad <fred.konrad@greensocs.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdbool.h>
+
+bool cexe_is_enabled(void);
+
+bool cexe_is_enabled(void)
+{
+ return false;
+}
@@ -7,3 +7,11 @@ int64_t cpu_get_icount(int with_bias)
{
abort();
}
+
+void icount_warp_rt(void *opaque)
+{
+ /*
+ * Should not happen, as cexe_is_enabled() always return false.
+ */
+ abort();
+}