[RFC PATCH 1/2] new clock for migration routine

Umesh Deshapnde
2011-07-22T19:58:15Z

This patch implements a migration clock, whose implementation is similar to the
existing rt_clock. This allows the migration timer to run in parallel to other
timers in the rt_clock. In the next patch, this clock is used to create a new
timer from the migration thread that calls the VM migration routine on the
source side.

Signed-off-by: Umesh Deshpande <udeshpan@redhat.com>
---
qemu-timer.c | 29 +++++++++++++++++++++++++++--
qemu-timer.h | 3 +++
2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/qemu-timer.c b/qemu-timer.c
index 72066c7..91e356f 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -144,6 +144,7 @@ void cpu_disable_ticks(void)
#define QEMU_CLOCK_REALTIME 0
#define QEMU_CLOCK_VIRTUAL 1
#define QEMU_CLOCK_HOST 2
+#define QEMU_CLOCK_MIGRATE 3

struct QEMUClock {
int type;
@@ -364,9 +365,10 @@ next:
}
}

-#define QEMU_NUM_CLOCKS 3
+#define QEMU_NUM_CLOCKS 4

QEMUClock *rt_clock;
+QEMUClock *migration_clock;
QEMUClock *vm_clock;
QEMUClock *host_clock;

@@ -561,12 +563,31 @@ int qemu_timer_pending(QEMUTimer *ts)
return 0;
}

+int64_t qemu_timer_difference(QEMUTimer *ts, QEMUClock *clock)
+{
+ int64_t expire_time, current_time;
+ QEMUTimer *t;
+
+ current_time = qemu_get_clock_ms(clock);
+ for (t = active_timers[clock->type]; t != NULL; t = t->next) {
+ if (t == ts) {
+ expire_time = ts->expire_time / SCALE_MS;
+ if (current_time >= expire_time) {
+ return 0;
+ } else {
+ return expire_time - current_time;
+ }
+ }
+ }
+ return 0;
+}
+
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time)
{
return qemu_timer_expired_ns(timer_head, current_time * timer_head->scale);
}

-static void qemu_run_timers(QEMUClock *clock)
+void qemu_run_timers(QEMUClock *clock)
{
QEMUTimer **ptimer_head, *ts;
int64_t current_time;
@@ -595,6 +616,9 @@ int64_t qemu_get_clock_ns(QEMUClock *clock)
switch(clock->type) {
case QEMU_CLOCK_REALTIME:
return get_clock();
+
+ case QEMU_CLOCK_MIGRATE:
+ return get_clock();
default:
case QEMU_CLOCK_VIRTUAL:
if (use_icount) {
@@ -610,6 +634,7 @@ int64_t qemu_get_clock_ns(QEMUClock *clock)
void init_clocks(void)
{
rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
+ migration_clock = qemu_new_clock(QEMU_CLOCK_MIGRATE);
vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
host_clock = qemu_new_clock(QEMU_CLOCK_HOST);

diff --git a/qemu-timer.h b/qemu-timer.h
index 06cbe20..014b70b 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -23,6 +23,7 @@ typedef void QEMUTimerCB(void *opaque);
machine is stopped. The real time clock has a frequency of 1000
Hz. */
extern QEMUClock *rt_clock;
+extern QEMUClock *migration_clock;

/* The virtual clock is only run during the emulation. It is stopped
when the virtual machine is stopped. Virtual timers use a high
@@ -45,7 +46,9 @@ QEMUTimer *qemu_new_timer(QEMUClock *clock, int scale,
void qemu_free_timer(QEMUTimer *ts);
void qemu_del_timer(QEMUTimer *ts);
void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time);
+void qemu_run_timers(QEMUClock *clock);
int qemu_timer_pending(QEMUTimer *ts);
+int64_t qemu_timer_difference(QEMUTimer *ts, QEMUClock *);
int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);

void qemu_run_all_timers(void);
--
1.7.4.1