On 15/08/19 11:13, Yury Kotov wrote: > Ping ping Hi,
sorry for the delay, I was waiting for the 4.1 release. I would like to make a small change so that preemption of QEMU does not result in overly long sleeps. The following patch on top of yours computes the throttle-end time just once. Of course you can still be unlucky if you are preempted at the wrong time, but the window becomes much smaller. diff --git a/cpus.c b/cpus.c index d091dbd..d7e2145 100644 --- a/cpus.c +++ b/cpus.c @@ -781,7 +781,7 @@ static void cpu_throttle_thread(CPUState *cpu, run_on_cpu_data opaque) { double pct; double throttle_ratio; - int64_t sleeptime_ns; + int64_t sleeptime_ns, end; if (!cpu_throttle_get_percentage()) { return; @@ -792,18 +792,17 @@ static void cpu_throttle_thread(CPUState *cpu, run_on_cpu_data opaque) /* Add 1ns to fix double's rounding error (like 0.9999999...) */ sleeptime_ns = (int64_t)(throttle_ratio * CPU_THROTTLE_TIMESLICE_NS + 1); - while (sleeptime_ns >= SCALE_MS && !cpu->stop) { - int64_t start, end; - start = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); - qemu_cond_timedwait(cpu->halt_cond, &qemu_global_mutex, - sleeptime_ns / SCALE_MS); - end = qemu_clock_get_ns(QEMU_CLOCK_REALTIME); - sleeptime_ns -= end - start; - } - if (sleeptime_ns >= SCALE_US && !cpu->stop) { - qemu_mutex_unlock_iothread(); - g_usleep(sleeptime_ns / SCALE_US); - qemu_mutex_lock_iothread(); + end = 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 = end - qemu_clock_get_ns(QEMU_CLOCK_REALTIME); } atomic_set(&cpu->throttle_thread_scheduled, 0); }