diff options
author | Paolo Bonzini <pbonzini@redhat.com> | 2018-01-11 13:53:12 +0100 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2018-01-16 14:54:51 +0100 |
commit | db08b687cdd5319286665aabd34f82665630416f (patch) | |
tree | e93ceecd86e566043dc06fd7c7e1be9a99fc8aae | |
parent | b39e3f34c9de7ead6a11a74aa2de78baf41d81a7 (diff) |
cpus: unify qemu_*_wait_io_event
Except for round-robin TCG, every other accelerator is using more or
less the same code around qemu_wait_io_event_common. The exception
is HAX, which also has to eat the dummy APC that is queued by
qemu_cpu_kick_thread.
We can add the SleepEx call to qemu_wait_io_event under "if
(!tcg_enabled())", since that is the condition that is used in
qemu_cpu_kick_thread, and unify the function for KVM, HAX, HVF and
multi-threaded TCG. Single-threaded TCG code can also be simplified
since it is only used in the round-robin, sleep-if-all-CPUs-idle case.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | cpus.c | 49 |
1 files changed, 17 insertions, 32 deletions
@@ -909,7 +909,8 @@ static void kick_tcg_thread(void *opaque) static void start_tcg_kick_timer(void) { - if (!mttcg_enabled && !tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) { + assert(!mttcg_enabled); + if (!tcg_kick_vcpu_timer && CPU_NEXT(first_cpu)) { tcg_kick_vcpu_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, kick_tcg_thread, NULL); timer_mod(tcg_kick_vcpu_timer, qemu_tcg_next_kick()); @@ -918,6 +919,7 @@ static void start_tcg_kick_timer(void) static void stop_tcg_kick_timer(void) { + assert(!mttcg_enabled); if (tcg_kick_vcpu_timer) { timer_del(tcg_kick_vcpu_timer); tcg_kick_vcpu_timer = NULL; @@ -1137,18 +1139,9 @@ static void qemu_wait_io_event_common(CPUState *cpu) process_queued_cpu_work(cpu); } -static bool qemu_tcg_should_sleep(CPUState *cpu) +static void qemu_tcg_rr_wait_io_event(CPUState *cpu) { - if (mttcg_enabled) { - return cpu_thread_is_idle(cpu); - } else { - return all_cpu_threads_idle(); - } -} - -static void qemu_tcg_wait_io_event(CPUState *cpu) -{ - while (qemu_tcg_should_sleep(cpu)) { + while (all_cpu_threads_idle()) { stop_tcg_kick_timer(); qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); } @@ -1158,20 +1151,18 @@ static void qemu_tcg_wait_io_event(CPUState *cpu) qemu_wait_io_event_common(cpu); } -static void qemu_kvm_wait_io_event(CPUState *cpu) +static void qemu_wait_io_event(CPUState *cpu) { while (cpu_thread_is_idle(cpu)) { qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); } - qemu_wait_io_event_common(cpu); -} - -static void qemu_hvf_wait_io_event(CPUState *cpu) -{ - while (cpu_thread_is_idle(cpu)) { - qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); +#ifdef _WIN32 + /* Eat dummy APC queued by qemu_cpu_kick_thread. */ + if (!tcg_enabled()) { + SleepEx(0, TRUE); } +#endif qemu_wait_io_event_common(cpu); } @@ -1207,7 +1198,7 @@ static void *qemu_kvm_cpu_thread_fn(void *arg) cpu_handle_guest_debug(cpu); } } - qemu_kvm_wait_io_event(cpu); + qemu_wait_io_event(cpu); } while (!cpu->unplug || cpu_can_run(cpu)); qemu_kvm_destroy_vcpu(cpu); @@ -1253,7 +1244,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg) exit(1); } qemu_mutex_lock_iothread(); - qemu_wait_io_event_common(cpu); + qemu_wait_io_event(cpu); } return NULL; @@ -1470,7 +1461,7 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg) atomic_mb_set(&cpu->exit_request, 0); } - qemu_tcg_wait_io_event(cpu ? cpu : QTAILQ_FIRST(&cpus)); + qemu_tcg_rr_wait_io_event(cpu ? cpu : QTAILQ_FIRST(&cpus)); deal_with_unplugged_cpus(); } @@ -1501,13 +1492,7 @@ static void *qemu_hax_cpu_thread_fn(void *arg) } } - while (cpu_thread_is_idle(cpu)) { - qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); - } -#ifdef _WIN32 - SleepEx(0, TRUE); -#endif - qemu_wait_io_event_common(cpu); + qemu_wait_io_event(cpu); } return NULL; } @@ -1544,7 +1529,7 @@ static void *qemu_hvf_cpu_thread_fn(void *arg) cpu_handle_guest_debug(cpu); } } - qemu_hvf_wait_io_event(cpu); + qemu_wait_io_event(cpu); } while (!cpu->unplug || cpu_can_run(cpu)); hvf_vcpu_destroy(cpu); @@ -1623,7 +1608,7 @@ static void *qemu_tcg_cpu_thread_fn(void *arg) } atomic_mb_set(&cpu->exit_request, 0); - qemu_tcg_wait_io_event(cpu); + qemu_wait_io_event(cpu); } return NULL; |