From: KONRAD Frederic <fred.kon...@greensocs.com> This introduces a new timer based only on instruction counter and without any compensation.
Signed-off-by: KONRAD Frederic <fred.kon...@greensocs.com> --- cpus.c | 21 +++++++++++++-------- include/qemu/timer.h | 9 ++++++++- qemu-timer.c | 8 +++++++- stubs/cpu-get-icount.c | 2 +- 4 files changed, 29 insertions(+), 11 deletions(-) diff --git a/cpus.c b/cpus.c index 0f7d0ea..0ae6798 100644 --- a/cpus.c +++ b/cpus.c @@ -137,7 +137,7 @@ typedef struct TimersState { static TimersState timers_state; /* Return the virtual CPU time, based on the instruction counter. */ -static int64_t cpu_get_icount_locked(void) +static int64_t cpu_get_icount_locked(int with_bias) { int64_t icount; CPUState *cpu = current_cpu; @@ -149,17 +149,22 @@ static int64_t cpu_get_icount_locked(void) } icount -= (cpu->icount_decr.u16.low + cpu->icount_extra); } - return timers_state.qemu_icount_bias + cpu_icount_to_ns(icount); + + if (with_bias) { + return timers_state.qemu_icount_bias + cpu_icount_to_ns(icount); + } else { + return cpu_icount_to_ns(icount); + } } -int64_t cpu_get_icount(void) +int64_t cpu_get_icount(int with_bias) { int64_t icount; unsigned start; do { start = seqlock_read_begin(&timers_state.vm_clock_seqlock); - icount = cpu_get_icount_locked(); + icount = cpu_get_icount_locked(with_bias); } while (seqlock_read_retry(&timers_state.vm_clock_seqlock, start)); return icount; @@ -177,7 +182,7 @@ int64_t cpu_get_ticks(void) int64_t ticks; if (use_icount) { - return cpu_get_icount(); + return cpu_get_icount(true); } ticks = timers_state.cpu_ticks_offset; @@ -292,7 +297,7 @@ static void icount_adjust(void) seqlock_write_lock(&timers_state.vm_clock_seqlock); cur_time = cpu_get_clock_locked(); - cur_icount = cpu_get_icount_locked(); + cur_icount = cpu_get_icount_locked(true); delta = cur_icount - cur_time; /* FIXME: This is a very crude algorithm, somewhat prone to oscillation. */ @@ -355,7 +360,7 @@ static void icount_warp_rt(void *opaque) * far ahead of real time. */ int64_t cur_time = cpu_get_clock_locked(); - int64_t cur_icount = cpu_get_icount_locked(); + int64_t cur_icount = cpu_get_icount_locked(true); int64_t delta = cur_time - cur_icount; warp_delta = MIN(warp_delta, delta); } @@ -1555,7 +1560,7 @@ void dump_drift_info(FILE *f, fprintf_function cpu_fprintf) } cpu_fprintf(f, "Host - Guest clock %"PRIi64" ms\n", - (cpu_get_clock() - cpu_get_icount())/SCALE_MS); + (cpu_get_clock() - cpu_get_icount(true))/SCALE_MS); if (icount_align_option) { cpu_fprintf(f, "Max guest delay %"PRIi64" ms\n", -max_delay/SCALE_MS); cpu_fprintf(f, "Max guest advance %"PRIi64" ms\n", max_advance/SCALE_MS); diff --git a/include/qemu/timer.h b/include/qemu/timer.h index 5f5210d..16bafde 100644 --- a/include/qemu/timer.h +++ b/include/qemu/timer.h @@ -36,12 +36,19 @@ * is suspended, and it will reflect system time changes the host may * undergo (e.g. due to NTP). The host clock has the same precision as * the virtual clock. + * + * @QEMU_CLOCK_ICOUNT: icount clock + * + * The icount clock is based on instruction counter without any compensation for + * speed. It will run only when instruction are executed and make only sense in + * icount mode. */ typedef enum { QEMU_CLOCK_REALTIME = 0, QEMU_CLOCK_VIRTUAL = 1, QEMU_CLOCK_HOST = 2, + QEMU_CLOCK_ICOUNT = 3, QEMU_CLOCK_MAX } QEMUClockType; @@ -743,7 +750,7 @@ static inline int64_t get_clock(void) #endif /* icount */ -int64_t cpu_get_icount(void); +int64_t cpu_get_icount(int with_bias); int64_t cpu_get_clock(void); int64_t cpu_get_clock_offset(void); int64_t cpu_icount_to_ns(int64_t icount); diff --git a/qemu-timer.c b/qemu-timer.c index 00a5d35..3be80b1 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -554,7 +554,7 @@ int64_t qemu_clock_get_ns(QEMUClockType type) default: case QEMU_CLOCK_VIRTUAL: if (use_icount) { - return cpu_get_icount(); + return cpu_get_icount(true); } else { return cpu_get_clock(); } @@ -566,6 +566,12 @@ int64_t qemu_clock_get_ns(QEMUClockType type) notifier_list_notify(&clock->reset_notifiers, &now); } return now; + case QEMU_CLOCK_ICOUNT: + if (use_icount) { + return cpu_get_icount(false); + } else { + return -1; + } } } diff --git a/stubs/cpu-get-icount.c b/stubs/cpu-get-icount.c index d685859..1968de7 100644 --- a/stubs/cpu-get-icount.c +++ b/stubs/cpu-get-icount.c @@ -3,7 +3,7 @@ int use_icount; -int64_t cpu_get_icount(void) +int64_t cpu_get_icount(int with_bias) { abort(); } -- 1.9.0