Commit eda5f7c6 authored by Alex Bennée's avatar Alex Bennée
Browse files

cpu-exec: update icount after each TB_EXIT



There is no particular reason we shouldn't update the global system
icount time as we exit each TranslationBlock run. This ensures the
main-loop doesn't have to wait until we exit to the outer loop for
executed instructions to be credited to timer_state.

The prepare_icount_for_run function is slightly tweaked to match the
logic we run in cpu_loop_exec_tb.

Based on Paolo's original suggestion.

Signed-off-by: default avatarAlex Bennée <alex.bennee@linaro.org>
parent 512d3c80
Loading
Loading
Loading
Loading
+7 −7
Original line number Diff line number Diff line
@@ -600,13 +600,13 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
    /* Instruction counter expired.  */
    assert(use_icount);
#ifndef CONFIG_USER_ONLY
    if (cpu->icount_extra) {
    /* Ensure global icount has gone forward */
    cpu_update_icount(cpu);
    /* Refill decrementer and continue execution.  */
        cpu->icount_extra += insns_left;
        insns_left = MIN(0xffff, cpu->icount_extra);
        cpu->icount_extra -= insns_left;
    insns_left = MIN(0xffff, cpu->icount_budget);
    cpu->icount_decr.u16.low = insns_left;
    } else {
    cpu->icount_extra = cpu->icount_budget - insns_left;
    if (!cpu->icount_extra) {
        /* Execute any remaining instructions, then let the main loop
         * handle the next event.
         */
+5 −13
Original line number Diff line number Diff line
@@ -1211,8 +1211,7 @@ static void handle_icount_deadline(void)
static void prepare_icount_for_run(CPUState *cpu)
{
    if (use_icount) {
        int64_t count;
        int decr;
        int insns_left;

        /* These should always be cleared by process_icount_data after
         * each vCPU execution. However u16.high can be raised
@@ -1221,17 +1220,10 @@ static void prepare_icount_for_run(CPUState *cpu)
        g_assert(cpu->icount_decr.u16.low == 0);
        g_assert(cpu->icount_extra == 0);


        count = tcg_get_icount_limit();

        /* To calculate what we have executed so far we need to know
         * what we originally budgeted to run this cycle */
        cpu->icount_budget = count;

        decr = (count > 0xffff) ? 0xffff : count;
        count -= decr;
        cpu->icount_decr.u16.low = decr;
        cpu->icount_extra = count;
        cpu->icount_budget = tcg_get_icount_limit();
        insns_left = MIN(0xffff, cpu->icount_budget);
        cpu->icount_decr.u16.low = insns_left;
        cpu->icount_extra = cpu->icount_budget - insns_left;
    }
}