On 01/07/16 19:29, Alvise Rigo wrote: > Hi Sergey, > > On Mon, Jun 20, 2016 at 12:28 AM, Sergey Fedorov > <sergey.fedo...@linaro.org> wrote: >> diff --git a/cpu-exec-common.c b/cpu-exec-common.c >> index 8184e0662cbd..3056324738f8 100644 >> --- a/cpu-exec-common.c >> +++ b/cpu-exec-common.c >> @@ -25,6 +25,7 @@ >> >> bool exit_request; >> CPUState *tcg_current_cpu; >> +int tcg_pending_cpus; >> >> /* exit the current TB, but without causing any exception to be raised */ >> void cpu_loop_exit_noexc(CPUState *cpu) >> @@ -78,6 +79,15 @@ void cpu_loop_exit_restore(CPUState *cpu, uintptr_t pc) >> siglongjmp(cpu->jmp_env, 1); >> } >> >> +static int safe_work_pending; >> + >> +void wait_safe_cpu_work(void) >> +{ >> + while (atomic_mb_read(&safe_work_pending) > 0) { >> + wait_cpu_work(); >> + } >> +} >> + > Is this piece of code deadlock-safe once we are in mttcg mode?
It is supposed to be deadlock-safe. > What happens when two threads call simultaneously async_safe_run_on_cpu? > In this case each thread will roughly: - exit its execution loop; - take BQL; - decrement 'tcg_pending_cpus', signal 'qemu_work_cond' if zero; - start processing its work queue; - encountering safe work wait on 'qemu_work_cond' for 'tcg_pending_cpus' to become zero; - reacquire BQL; - process the safe work; - decrement 'safe_work_pending', signal 'qemu_work_cond' if zero; - when finished processing work, wait on 'qemu_work_cond' for 'safe_work_pending' to become zero; - reacquire BQL; - continue execution (releasing BQL). Hope this will help. Kind regards, Sergey.