mirror of https://github.com/xqemu/xqemu.git
cpus: move icount preparation out of tcg_exec_cpu
As icount is only supported for single-threaded execution due to the requirement for determinism let's remove it from the common tcg_exec_cpu path. Also remove the additional fiddling which shouldn't be required as the icount counters should all be rectified as you enter the loop. Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
This commit is contained in:
parent
243c5f77f6
commit
0524838225
69
cpus.c
69
cpus.c
|
@ -1179,6 +1179,46 @@ static void handle_icount_deadline(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void prepare_icount_for_run(CPUState *cpu)
|
||||||
|
{
|
||||||
|
if (use_icount) {
|
||||||
|
int64_t count;
|
||||||
|
int decr;
|
||||||
|
|
||||||
|
/* These should always be cleared by process_icount_data after
|
||||||
|
* each vCPU execution. However u16.high can be raised
|
||||||
|
* asynchronously by cpu_exit/cpu_interrupt/tcg_handle_interrupt
|
||||||
|
*/
|
||||||
|
g_assert(cpu->icount_decr.u16.low == 0);
|
||||||
|
g_assert(cpu->icount_extra == 0);
|
||||||
|
|
||||||
|
|
||||||
|
count = tcg_get_icount_limit();
|
||||||
|
|
||||||
|
timers_state.qemu_icount += count;
|
||||||
|
decr = (count > 0xffff) ? 0xffff : count;
|
||||||
|
count -= decr;
|
||||||
|
cpu->icount_decr.u16.low = decr;
|
||||||
|
cpu->icount_extra = count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void process_icount_data(CPUState *cpu)
|
||||||
|
{
|
||||||
|
if (use_icount) {
|
||||||
|
/* Fold pending instructions back into the
|
||||||
|
instruction counter, and clear the interrupt flag. */
|
||||||
|
timers_state.qemu_icount -= (cpu->icount_decr.u16.low
|
||||||
|
+ cpu->icount_extra);
|
||||||
|
|
||||||
|
/* Reset the counters */
|
||||||
|
cpu->icount_decr.u16.low = 0;
|
||||||
|
cpu->icount_extra = 0;
|
||||||
|
replay_account_executed_instructions();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int tcg_cpu_exec(CPUState *cpu)
|
static int tcg_cpu_exec(CPUState *cpu)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
@ -1189,20 +1229,6 @@ static int tcg_cpu_exec(CPUState *cpu)
|
||||||
#ifdef CONFIG_PROFILER
|
#ifdef CONFIG_PROFILER
|
||||||
ti = profile_getclock();
|
ti = profile_getclock();
|
||||||
#endif
|
#endif
|
||||||
if (use_icount) {
|
|
||||||
int64_t count;
|
|
||||||
int decr;
|
|
||||||
timers_state.qemu_icount -= (cpu->icount_decr.u16.low
|
|
||||||
+ cpu->icount_extra);
|
|
||||||
cpu->icount_decr.u16.low = 0;
|
|
||||||
cpu->icount_extra = 0;
|
|
||||||
count = tcg_get_icount_limit();
|
|
||||||
timers_state.qemu_icount += count;
|
|
||||||
decr = (count > 0xffff) ? 0xffff : count;
|
|
||||||
count -= decr;
|
|
||||||
cpu->icount_decr.u16.low = decr;
|
|
||||||
cpu->icount_extra = count;
|
|
||||||
}
|
|
||||||
qemu_mutex_unlock_iothread();
|
qemu_mutex_unlock_iothread();
|
||||||
cpu_exec_start(cpu);
|
cpu_exec_start(cpu);
|
||||||
ret = cpu_exec(cpu);
|
ret = cpu_exec(cpu);
|
||||||
|
@ -1211,15 +1237,6 @@ static int tcg_cpu_exec(CPUState *cpu)
|
||||||
#ifdef CONFIG_PROFILER
|
#ifdef CONFIG_PROFILER
|
||||||
tcg_time += profile_getclock() - ti;
|
tcg_time += profile_getclock() - ti;
|
||||||
#endif
|
#endif
|
||||||
if (use_icount) {
|
|
||||||
/* Fold pending instructions back into the
|
|
||||||
instruction counter, and clear the interrupt flag. */
|
|
||||||
timers_state.qemu_icount -= (cpu->icount_decr.u16.low
|
|
||||||
+ cpu->icount_extra);
|
|
||||||
cpu->icount_decr.u32 = 0;
|
|
||||||
cpu->icount_extra = 0;
|
|
||||||
replay_account_executed_instructions();
|
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1306,7 +1323,13 @@ static void *qemu_tcg_rr_cpu_thread_fn(void *arg)
|
||||||
|
|
||||||
if (cpu_can_run(cpu)) {
|
if (cpu_can_run(cpu)) {
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
|
prepare_icount_for_run(cpu);
|
||||||
|
|
||||||
r = tcg_cpu_exec(cpu);
|
r = tcg_cpu_exec(cpu);
|
||||||
|
|
||||||
|
process_icount_data(cpu);
|
||||||
|
|
||||||
if (r == EXCP_DEBUG) {
|
if (r == EXCP_DEBUG) {
|
||||||
cpu_handle_guest_debug(cpu);
|
cpu_handle_guest_debug(cpu);
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue