Commit ac03ee53 authored by Emilio G. Cota's avatar Emilio G. Cota Committed by Richard Henderson
Browse files

cpu-exec: lookup/generate TB outside exclusive region during step_atomic



Now that all code generation has been converted to check CF_PARALLEL, we can
generate !CF_PARALLEL code without having yet set !parallel_cpus --
and therefore without having to be in the exclusive region during
cpu_exec_step_atomic.

While at it, merge cpu_exec_step into cpu_exec_step_atomic.

Reviewed-by: default avatarRichard Henderson <rth@twiddle.net>
Signed-off-by: default avatarEmilio G. Cota <cota@braap.org>
Signed-off-by: default avatarRichard Henderson <richard.henderson@linaro.org>
parent e82d5a24
Loading
Loading
Loading
Loading
+14 −16
Original line number Diff line number Diff line
@@ -223,30 +223,40 @@ static void cpu_exec_nocache(CPUState *cpu, int max_cycles,
}
#endif

static void cpu_exec_step(CPUState *cpu)
void cpu_exec_step_atomic(CPUState *cpu)
{
    CPUClass *cc = CPU_GET_CLASS(cpu);
    TranslationBlock *tb;
    target_ulong cs_base, pc;
    uint32_t flags;
    uint32_t cflags = 1 | CF_IGNORE_ICOUNT;
    uint32_t cf_mask = cflags & CF_HASH_MASK;

    if (sigsetjmp(cpu->jmp_env, 0) == 0) {
        tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags,
                                  cflags & CF_HASH_MASK);
        tb = tb_lookup__cpu_state(cpu, &pc, &cs_base, &flags, cf_mask);
        if (tb == NULL) {
            mmap_lock();
            tb_lock();
            tb = tb_htable_lookup(cpu, pc, cs_base, flags, cf_mask);
            if (likely(tb == NULL)) {
                tb = tb_gen_code(cpu, pc, cs_base, flags, cflags);
            }
            tb_unlock();
            mmap_unlock();
        }

        start_exclusive();

        /* Since we got here, we know that parallel_cpus must be true.  */
        parallel_cpus = false;
        cc->cpu_exec_enter(cpu);
        /* execute the generated code */
        trace_exec_tb(tb, pc);
        cpu_tb_exec(cpu, tb);
        cc->cpu_exec_exit(cpu);
        parallel_cpus = true;

        end_exclusive();
    } else {
        /* We may have exited due to another problem here, so we need
         * to reset any tb_locks we may have taken but didn't release.
@@ -260,18 +270,6 @@ static void cpu_exec_step(CPUState *cpu)
    }
}

void cpu_exec_step_atomic(CPUState *cpu)
{
    start_exclusive();

    /* Since we got here, we know that parallel_cpus must be true.  */
    parallel_cpus = false;
    cpu_exec_step(cpu);
    parallel_cpus = true;

    end_exclusive();
}

struct tb_desc {
    target_ulong pc;
    target_ulong cs_base;