@@ -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);
@@ -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);
@@ -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;
+ }
}
}
@@ -3,7 +3,7 @@
int use_icount;
-int64_t cpu_get_icount(void)
+int64_t cpu_get_icount(int with_bias)
{
abort();
}