[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC V7 02/10] icount: introduce icount timer.
From: |
fred . konrad |
Subject: |
[Qemu-devel] [RFC V7 02/10] icount: introduce icount timer. |
Date: |
Wed, 17 Sep 2014 10:26:42 +0200 |
From: KONRAD Frederic <address@hidden>
This introduces a new timer based only on instruction counter and without any
compensation.
Signed-off-by: KONRAD Frederic <address@hidden>
---
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
- [Qemu-devel] [RFC V7 00/10] Reverse execution., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 01/10] migration: make qemu_savevm_state public., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 02/10] icount: introduce icount timer.,
fred . konrad <=
- [Qemu-devel] [RFC V7 03/10] icount: check for icount clock deadline when cpu loop exits., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 05/10] trace-events: add reverse-execution events., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 04/10] icount: make icount extra computed on icount clock as well., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 06/10] introduce reverse execution mechanism., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 08/10] cpu-exec: trigger a debug request when rexec stops., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 09/10] rexec: synchronize icount on the next event., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 10/10] rexec: allow to enable reverse execution., fred . konrad, 2014/09/17
- [Qemu-devel] [RFC V7 07/10] gdbstub: allow reverse execution in gdb stub., fred . konrad, 2014/09/17