[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 4/7] icount: introduce icount timer.
From: |
fred . konrad |
Subject: |
[Qemu-devel] [PATCH 4/7] icount: introduce icount timer. |
Date: |
Fri, 1 Aug 2014 01:37:12 +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 98e1203..e8971e3 100644
--- a/cpus.c
+++ b/cpus.c
@@ -140,7 +140,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;
@@ -152,17 +152,22 @@ static int64_t cpu_get_icount_locked(void)
}
icount -= (cpu->icount_decr.u16.low + cpu->icount_extra);
}
- return timers_state.qemu_icount_bias + (icount << icount_time_shift);
+
+ if (with_bias) {
+ return timers_state.qemu_icount_bias + (icount << icount_time_shift);
+ } else {
+ return icount << icount_time_shift;
+ }
}
-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;
@@ -175,7 +180,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;
@@ -290,7 +295,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.
*/
@@ -353,7 +358,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);
}
@@ -1557,7 +1562,7 @@ void qmp_inject_nmi(Error **errp)
void dump_drift_info(FILE *f, fprintf_function cpu_fprintf)
{
cpu_fprintf(f, "Host - Guest clock %ld(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 %ld(ms)\n", -max_delay/SCALE_MS);
cpu_fprintf(f, "Max guest advance %ld(ms)\n", max_advance/SCALE_MS);
diff --git a/include/qemu/timer.h b/include/qemu/timer.h
index 102f442..1ad0f87 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);
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] [PATCH 0/7] icount migration and clock., fred . konrad, 2014/07/31
- [Qemu-devel] [PATCH 2/7] migration: migrate icount fields., fred . konrad, 2014/07/31
- [Qemu-devel] [PATCH 6/7] icount: make icount extra computed on icount clock as well., fred . konrad, 2014/07/31
- [Qemu-devel] [PATCH 3/7] migration: make qemu_savevm_state public., fred . konrad, 2014/07/31
- [Qemu-devel] [PATCH 1/7] icount: put icount variables into TimerState., fred . konrad, 2014/07/31
- [Qemu-devel] [PATCH 5/7] icount: check for icount clock deadline when cpu loop exits., fred . konrad, 2014/07/31
- [Qemu-devel] [PATCH 4/7] icount: introduce icount timer.,
fred . konrad <=
- [Qemu-devel] [PATCH 7/7] timer: add cpu_icount_to_ns function., fred . konrad, 2014/07/31