#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/config-file.h"
+#include "qemu/cutils.h"
#include "migration/vmstate.h"
#include "monitor/monitor.h"
#include "qapi/error.h"
#include "qemu/bitmap.h"
#include "qemu/seqlock.h"
#include "qemu/guest-random.h"
-#include "tcg.h"
+#include "tcg/tcg.h"
#include "hw/nmi.h"
#include "sysemu/replay.h"
#include "sysemu/runstate.h"
void configure_icount(QemuOpts *opts, Error **errp)
{
- const char *option;
- char *rem_str = NULL;
+ const char *option = qemu_opt_get(opts, "shift");
+ bool sleep = qemu_opt_get_bool(opts, "sleep", true);
+ bool align = qemu_opt_get_bool(opts, "align", false);
+ long time_shift = -1;
- option = qemu_opt_get(opts, "shift");
- if (!option) {
- if (qemu_opt_get(opts, "align") != NULL) {
- error_setg(errp, "Please specify shift option when using align");
- }
+ if (!option && qemu_opt_get(opts, "align")) {
+ error_setg(errp, "Please specify shift option when using align");
return;
}
- icount_sleep = qemu_opt_get_bool(opts, "sleep", true);
- if (icount_sleep) {
- timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
- icount_timer_cb, NULL);
- }
-
- icount_align_option = qemu_opt_get_bool(opts, "align", false);
-
- if (icount_align_option && !icount_sleep) {
+ if (align && !sleep) {
error_setg(errp, "align=on and sleep=off are incompatible");
+ return;
}
+
if (strcmp(option, "auto") != 0) {
- errno = 0;
- timers_state.icount_time_shift = strtol(option, &rem_str, 0);
- if (errno != 0 || *rem_str != '\0' || !strlen(option)) {
+ if (qemu_strtol(option, NULL, 0, &time_shift) < 0
+ || time_shift < 0 || time_shift > MAX_ICOUNT_SHIFT) {
error_setg(errp, "icount: Invalid shift value");
+ return;
}
- use_icount = 1;
- return;
} else if (icount_align_option) {
error_setg(errp, "shift=auto and align=on are incompatible");
+ return;
} else if (!icount_sleep) {
error_setg(errp, "shift=auto and sleep=off are incompatible");
+ return;
+ }
+
+ icount_sleep = sleep;
+ if (icount_sleep) {
+ timers_state.icount_warp_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL_RT,
+ icount_timer_cb, NULL);
+ }
+
+ icount_align_option = align;
+
+ if (time_shift >= 0) {
+ timers_state.icount_time_shift = time_shift;
+ use_icount = 1;
+ return;
}
use_icount = 2;
int ret = 0;
if (runstate_is_running()) {
+ runstate_set(state);
cpu_disable_ticks();
pause_all_vcpus();
- runstate_set(state);
vm_state_notify(0, state);
if (send_stop) {
qapi_event_send_stop();
*/
deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
QEMU_TIMER_ATTR_ALL);
+ /* Check realtime timers, because they help with input processing */
+ deadline = qemu_soonest_timeout(deadline,
+ qemu_clock_deadline_ns_all(QEMU_CLOCK_REALTIME,
+ QEMU_TIMER_ATTR_ALL));
/* Maintain prior (possibly buggy) behaviour where if no deadline
* was set (as there is no QEMU_CLOCK_VIRTUAL timer) or it is more than
qemu_mutex_unlock(&qemu_global_mutex);
}
+void qemu_cond_wait_iothread(QemuCond *cond)
+{
+ qemu_cond_wait(cond, &qemu_global_mutex);
+}
+
static bool all_vcpus_paused(void)
{
CPUState *cpu;
{
CPUState *cpu;
+ if (!runstate_is_running()) {
+ return;
+ }
+
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
CPU_FOREACH(cpu) {
cpu_resume(cpu);