Richard Henderson <r...@twiddle.net> writes:

> On 01/19/2017 09:04 AM, Alex Bennée wrote:
>> +/* flush_all_helper: run fn across all cpus
>> + *
>> + * If the wait flag is set then the src cpu's helper will be queued as
>> + * "safe" work and the loop exited creating a synchronisation point
>> + * where all queued work will be finished before execution starts
>> + * again.
>> + */
>> +static void flush_all_helper(CPUState *src, bool wait,
>> +                             run_on_cpu_func fn, run_on_cpu_data d)
>> +{
>> +    CPUState *cpu;
>> +
>> +    if (!wait) {
>> +        CPU_FOREACH(cpu) {
>> +            if (cpu != src) {
>> +                async_run_on_cpu(cpu, fn, d);
>> +            } else {
>> +                g_assert(qemu_cpu_is_self(src));
>> +                fn(src, d);
>> +            }
>> +        }
>> +    } else {
>> +        CPU_FOREACH(cpu) {
>> +            if (cpu != src) {
>> +                async_run_on_cpu(cpu, fn, d);
>> +            } else {
>> +                async_safe_run_on_cpu(cpu, fn, d);
>> +            }
>> +
>> +        }
>> +        cpu_loop_exit(src);
>> +    }
>> +}
>
> What's the rationale for not having the target do the exit itself?  Surely it
> can tell, and simple end the TB after the insn.

It's more for the global sync functionality. I wanted to keep all the
guts of re-starting the loop with the correct async_safe_work all in one
place with a defined API for the guests rather than have them all do it
themselves.

For the common case of not needing to sync across the cores I agree the
guest is perfectly able to end the TB so its safe work completes next.
In fact the ARM helper calls do exactly that.

--
Alex Bennée

Reply via email to