int64_t cpu_get_icount_raw(void)
{
- int64_t icount;
CPUState *cpu = current_cpu;
- icount = atomic_read(&timers_state.qemu_icount);
if (cpu && cpu->running) {
if (!cpu->can_do_io) {
fprintf(stderr, "Bad icount read\n");
exit(1);
}
/* Take into account what has run */
- icount += cpu_get_icount_executed(cpu);
+ cpu_update_icount(cpu);
}
- return icount;
+#ifdef CONFIG_ATOMIC64
+ return atomic_read__nocheck(&timers_state.qemu_icount);
+#else /* FIXME: we need 64bit atomics to do this safely */
+ return timers_state.qemu_icount;
+#endif
}
/* Return the virtual CPU time, based on the instruction counter. */
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
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;
}
}