mirror of
https://github.com/qemu/qemu.git
synced 2025-07-29 14:43:25 +00:00
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: Alex Bennée <alex.bennee@linaro.org>
This commit is contained in:
parent
512d3c8071
commit
eda5f7c6a1
14
cpu-exec.c
14
cpu-exec.c
@ -600,13 +600,13 @@ static inline void cpu_loop_exec_tb(CPUState *cpu, TranslationBlock *tb,
|
|||||||
/* Instruction counter expired. */
|
/* Instruction counter expired. */
|
||||||
assert(use_icount);
|
assert(use_icount);
|
||||||
#ifndef CONFIG_USER_ONLY
|
#ifndef CONFIG_USER_ONLY
|
||||||
if (cpu->icount_extra) {
|
/* Ensure global icount has gone forward */
|
||||||
/* Refill decrementer and continue execution. */
|
cpu_update_icount(cpu);
|
||||||
cpu->icount_extra += insns_left;
|
/* Refill decrementer and continue execution. */
|
||||||
insns_left = MIN(0xffff, cpu->icount_extra);
|
insns_left = MIN(0xffff, cpu->icount_budget);
|
||||||
cpu->icount_extra -= insns_left;
|
cpu->icount_decr.u16.low = insns_left;
|
||||||
cpu->icount_decr.u16.low = insns_left;
|
cpu->icount_extra = cpu->icount_budget - insns_left;
|
||||||
} else {
|
if (!cpu->icount_extra) {
|
||||||
/* Execute any remaining instructions, then let the main loop
|
/* Execute any remaining instructions, then let the main loop
|
||||||
* handle the next event.
|
* handle the next event.
|
||||||
*/
|
*/
|
||||||
|
18
cpus.c
18
cpus.c
@ -1211,8 +1211,7 @@ static void handle_icount_deadline(void)
|
|||||||
static void prepare_icount_for_run(CPUState *cpu)
|
static void prepare_icount_for_run(CPUState *cpu)
|
||||||
{
|
{
|
||||||
if (use_icount) {
|
if (use_icount) {
|
||||||
int64_t count;
|
int insns_left;
|
||||||
int decr;
|
|
||||||
|
|
||||||
/* These should always be cleared by process_icount_data after
|
/* These should always be cleared by process_icount_data after
|
||||||
* each vCPU execution. However u16.high can be raised
|
* 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_decr.u16.low == 0);
|
||||||
g_assert(cpu->icount_extra == 0);
|
g_assert(cpu->icount_extra == 0);
|
||||||
|
|
||||||
|
cpu->icount_budget = tcg_get_icount_limit();
|
||||||
count = tcg_get_icount_limit();
|
insns_left = MIN(0xffff, cpu->icount_budget);
|
||||||
|
cpu->icount_decr.u16.low = insns_left;
|
||||||
/* To calculate what we have executed so far we need to know
|
cpu->icount_extra = cpu->icount_budget - insns_left;
|
||||||
* 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user