Stopped CPUs are parked until cpu_thread_is_idle() is true, so implement it for qemu-user. Share a part of the qemu-system's implementation.
Signed-off-by: Ilya Leoshkevich <i...@linux.ibm.com> --- accel/tcg/user-exec.c | 12 ++++++++++++ cpu-common.c | 19 +++++++++++++++++++ include/exec/cpu-common.h | 3 +++ include/sysemu/cpus.h | 1 - system/cpus.c | 17 ++++------------- 5 files changed, 38 insertions(+), 14 deletions(-) diff --git a/accel/tcg/user-exec.c b/accel/tcg/user-exec.c index 3ebace1e833..57a13c81fc4 100644 --- a/accel/tcg/user-exec.c +++ b/accel/tcg/user-exec.c @@ -1317,3 +1317,15 @@ void cpu_exit_syscall(CPUState *cs) { cs->in_syscall = false; } + +bool cpu_is_stopped(CPUState *cpu) +{ + return cpu->stopped; +} + +bool cpu_thread_is_idle(CPUState *cpu) +{ + int ret = cpu_thread_is_idle_common(cpu); + + return ret == -1 ? true : ret; +} diff --git a/cpu-common.c b/cpu-common.c index cb7c10a3915..2822ee9373d 100644 --- a/cpu-common.c +++ b/cpu-common.c @@ -497,3 +497,22 @@ void run_on_cpu(CPUState *cpu, run_on_cpu_func func, run_on_cpu_data data) { do_run_on_cpu(cpu, func, data, &bql); } + +bool cpu_work_list_empty(CPUState *cpu) +{ + return QSIMPLEQ_EMPTY_ATOMIC(&cpu->work_list); +} + +int cpu_thread_is_idle_common(CPUState *cpu) +{ + if (cpu->stop || !cpu_work_list_empty(cpu)) { + return 0; + } + if (cpu_is_stopped(cpu)) { + return 1; + } + if (!cpu->halted || cpu_has_work(cpu)) { + return 0; + } + return -1; +} diff --git a/include/exec/cpu-common.h b/include/exec/cpu-common.h index 32bd3cad83f..d7fc24bc13d 100644 --- a/include/exec/cpu-common.h +++ b/include/exec/cpu-common.h @@ -231,6 +231,9 @@ int cpu_exec_user(CPUState *cs); void cpu_enter_syscall(CPUState *cs); void cpu_exit_syscall(CPUState *cs); +int cpu_thread_is_idle_common(CPUState *cpu); +bool cpu_thread_is_idle(CPUState *cpu); + /** * env_archcpu(env) * @env: The architecture environment diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index b4a566cfe75..bfa3fd45650 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -21,7 +21,6 @@ void dummy_start_vcpu_thread(CPUState *); void cpus_kick_thread(CPUState *cpu); bool cpu_work_list_empty(CPUState *cpu); -bool cpu_thread_is_idle(CPUState *cpu); bool all_cpu_threads_idle(void); bool cpu_can_run(CPUState *cpu); void qemu_wait_io_event_common(CPUState *cpu); diff --git a/system/cpus.c b/system/cpus.c index fe84b822798..13072be26fa 100644 --- a/system/cpus.c +++ b/system/cpus.c @@ -75,21 +75,12 @@ bool cpu_is_stopped(CPUState *cpu) return cpu->stopped || !runstate_is_running(); } -bool cpu_work_list_empty(CPUState *cpu) -{ - return QSIMPLEQ_EMPTY_ATOMIC(&cpu->work_list); -} - bool cpu_thread_is_idle(CPUState *cpu) { - if (cpu->stop || !cpu_work_list_empty(cpu)) { - return false; - } - if (cpu_is_stopped(cpu)) { - return true; - } - if (!cpu->halted || cpu_has_work(cpu)) { - return false; + int ret = cpu_thread_is_idle_common(cpu); + + if (ret != -1) { + return ret; } if (cpus_accel->cpu_thread_is_idle) { return cpus_accel->cpu_thread_is_idle(cpu); -- 2.46.0