#include "qemu/osdep.h"
#include "qemu-common.h"
#include "qemu/config-file.h"
+#include "migration/vmstate.h"
#include "monitor/monitor.h"
#include "qapi/error.h"
#include "qapi/qapi-commands-misc.h"
#include "tcg.h"
#include "hw/nmi.h"
#include "sysemu/replay.h"
+#include "sysemu/runstate.h"
#include "hw/boards.h"
+#include "hw/hw.h"
#ifdef CONFIG_LINUX
#endif /* CONFIG_LINUX */
+static QemuMutex qemu_global_mutex;
+
int64_t max_delay;
int64_t max_advance;
assert(qtest_enabled());
aio_context = qemu_get_aio_context();
while (clock < dest) {
- int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+ int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+ QEMU_TIMER_ATTR_ALL);
int64_t warp = qemu_soonest_timeout(dest - clock, deadline);
seqlock_write_lock(&timers_state.vm_clock_seqlock,
/* We want to use the earliest deadline from ALL vm_clocks */
clock = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL_RT);
- deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+ deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+ ~QEMU_TIMER_ATTR_EXTERNAL);
if (deadline < 0) {
static bool notified;
if (!icount_sleep && !notified) {
{
double pct;
double throttle_ratio;
- long sleeptime_ns;
+ int64_t sleeptime_ns, endtime_ns;
if (!cpu_throttle_get_percentage()) {
return;
pct = (double)cpu_throttle_get_percentage()/100;
throttle_ratio = pct / (1 - pct);
- sleeptime_ns = (long)(throttle_ratio * CPU_THROTTLE_TIMESLICE_NS);
-
- qemu_mutex_unlock_iothread();
- g_usleep(sleeptime_ns / 1000); /* Convert ns to us for usleep call */
- qemu_mutex_lock_iothread();
+ /* Add 1ns to fix double's rounding error (like 0.9999999...) */
+ sleeptime_ns = (int64_t)(throttle_ratio * CPU_THROTTLE_TIMESLICE_NS + 1);
+ endtime_ns = qemu_clock_get_ns(QEMU_CLOCK_REALTIME) + sleeptime_ns;
+ while (sleeptime_ns > 0 && !cpu->stop) {
+ if (sleeptime_ns > SCALE_MS) {
+ qemu_cond_timedwait(cpu->halt_cond, &qemu_global_mutex,
+ sleeptime_ns / SCALE_MS);
+ } else {
+ qemu_mutex_unlock_iothread();
+ g_usleep(sleeptime_ns / SCALE_US);
+ qemu_mutex_lock_iothread();
+ }
+ sleeptime_ns = endtime_ns - qemu_clock_get_ns(QEMU_CLOCK_REALTIME);
+ }
atomic_set(&cpu->throttle_thread_scheduled, 0);
}
}
#endif /* !CONFIG_LINUX */
-static QemuMutex qemu_global_mutex;
-
static QemuThread io_thread;
/* cpu creation */
int64_t deadline;
if (replay_mode != REPLAY_MODE_PLAY) {
- deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+ /*
+ * Include all the timers, because they may need an attention.
+ * Too long CPU execution may create unnecessary delay in UI.
+ */
+ deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+ 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
{
assert(qemu_in_vcpu_thread());
if (use_icount) {
- int64_t deadline =
- qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+ int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL,
+ QEMU_TIMER_ATTR_ALL);
if (deadline == 0) {
/* Wake up other AioContexts. */