cpus: introduce cpu_update_icount helper
By holding off updates to timer_state.qemu_icount we can run into trouble when the non-vCPU thread needs to know the time. This helper ensures we atomically update timers_state.qemu_icount based on what has been currently executed. Signed-off-by: Alex Bennée <alex.bennee@linaro.org>
This commit is contained in:
parent
e4cd96571f
commit
512d3c8071
23
cpus.c
23
cpus.c
@ -232,12 +232,31 @@ static int64_t cpu_get_icount_executed(CPUState *cpu)
|
||||
return cpu->icount_budget - (cpu->icount_decr.u16.low + cpu->icount_extra);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the global shared timer_state.qemu_icount to take into
|
||||
* account executed instructions. This is done by the TCG vCPU
|
||||
* thread so the main-loop can see time has moved forward.
|
||||
*/
|
||||
void cpu_update_icount(CPUState *cpu)
|
||||
{
|
||||
int64_t executed = cpu_get_icount_executed(cpu);
|
||||
cpu->icount_budget -= executed;
|
||||
|
||||
#ifdef CONFIG_ATOMIC64
|
||||
atomic_set__nocheck(&timers_state.qemu_icount,
|
||||
atomic_read__nocheck(&timers_state.qemu_icount) +
|
||||
executed);
|
||||
#else /* FIXME: we need 64bit atomics to do this safely */
|
||||
timers_state.qemu_icount += executed;
|
||||
#endif
|
||||
}
|
||||
|
||||
int64_t cpu_get_icount_raw(void)
|
||||
{
|
||||
int64_t icount;
|
||||
CPUState *cpu = current_cpu;
|
||||
|
||||
icount = timers_state.qemu_icount;
|
||||
icount = atomic_read(&timers_state.qemu_icount);
|
||||
if (cpu && cpu->running) {
|
||||
if (!cpu->can_do_io) {
|
||||
fprintf(stderr, "Bad icount read\n");
|
||||
@ -1220,7 +1239,7 @@ static void process_icount_data(CPUState *cpu)
|
||||
{
|
||||
if (use_icount) {
|
||||
/* Account for executed instructions */
|
||||
timers_state.qemu_icount += cpu_get_icount_executed(cpu);
|
||||
cpu_update_icount(cpu);
|
||||
|
||||
/* Reset the counters */
|
||||
cpu->icount_decr.u16.low = 0;
|
||||
|
@ -869,6 +869,7 @@ int64_t cpu_get_icount_raw(void);
|
||||
int64_t cpu_get_icount(void);
|
||||
int64_t cpu_get_clock(void);
|
||||
int64_t cpu_icount_to_ns(int64_t icount);
|
||||
void cpu_update_icount(CPUState *cpu);
|
||||
|
||||
/*******************************************/
|
||||
/* host CPU ticks (if available) */
|
||||
|
Loading…
Reference in New Issue
Block a user