qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [RFC PATCH 10/9] qtest: add clock management
Date: Wed, 18 Jan 2012 15:31:47 +0100	[thread overview]
Message-ID: <1326897107-16340-1-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1326882794-31816-1-git-send-email-pbonzini@redhat.com>

This patch combines qtest and -icount together to turn the vm_clock
into a source that can be fully managed by the client.  To this end new
commands clock_step and clock_set are added.  Hooking them with libqtest
is left as an exercise to the reader.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 cpus.c       |   20 ++++++++++++++++++++
 cpus.h       |    2 ++
 qemu-timer.c |    2 +-
 qemu-timer.h |    1 +
 qtest.c      |   45 +++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 69 insertions(+), 1 deletions(-)

diff --git a/cpus.c b/cpus.c
index c4ca26a..2963797 100644
--- a/cpus.c
+++ b/cpus.c
@@ -34,6 +34,7 @@
 
 #include "qemu-thread.h"
 #include "cpus.h"
+#include "qtest.h"
 #include "main-loop.h"
 
 #ifndef _WIN32
@@ -238,6 +239,20 @@ static void icount_warp_rt(void *opaque)
     vm_clock_warp_start = -1;
 }
 
+void qtest_clock_warp(int64_t dest)
+{
+    int64_t clock = qemu_get_clock_ns(vm_clock);
+    assert(qtest_enabled());
+    while (clock < dest) {
+        int64_t deadline = qemu_clock_deadline(vm_clock);
+        int64_t warp = MIN(dest - clock, deadline);
+        qemu_icount_bias += warp;
+        qemu_run_timers(vm_clock);
+        clock = qemu_get_clock_ns(vm_clock);
+    }
+    qemu_notify_event();
+}
+
 void qemu_clock_warp(QEMUClock *clock)
 {
     int64_t deadline;
@@ -264,6 +279,11 @@ void qemu_clock_warp(QEMUClock *clock)
         return;
     }
 
+    if (qtest_enabled()) {
+        /* When testing, qtest commands advance icount.  */
+	return;
+    }
+
     vm_clock_warp_start = qemu_get_clock_ns(rt_clock);
     deadline = qemu_clock_deadline(vm_clock);
     if (deadline > 0) {
diff --git a/cpus.h b/cpus.h
index 4ea2fe2..b49c2f5 100644
--- a/cpus.h
+++ b/cpus.h
@@ -11,6 +11,8 @@ void cpu_synchronize_all_states(void);
 void cpu_synchronize_all_post_reset(void);
 void cpu_synchronize_all_post_init(void);
 
+void qtest_clock_warp(int64_t dest);
+
 /* vl.c */
 extern int smp_cores;
 extern int smp_threads;
diff --git a/qemu-timer.c b/qemu-timer.c
index cd026c6..cb246cb 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -397,7 +397,7 @@ 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;
diff --git a/qemu-timer.h b/qemu-timer.h
index de17f3b..661bbe7 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -59,6 +59,7 @@ int qemu_timer_pending(QEMUTimer *ts);
 int qemu_timer_expired(QEMUTimer *timer_head, int64_t current_time);
 uint64_t qemu_timer_expire_time_ns(QEMUTimer *ts);
 
+void qemu_run_timers(QEMUClock *clock);
 void qemu_run_all_timers(void);
 int qemu_alarm_pending(void);
 void configure_alarms(char const *opt);
diff --git a/qtest.c b/qtest.c
index 010befe..d7b38eb 100644
--- a/qtest.c
+++ b/qtest.c
@@ -18,6 +18,7 @@
 #include "memory.h"
 #include "hw/irq.h"
 #include "sysemu.h"
+#include "cpus.h"
 
 #define MAX_IRQ 256
 
@@ -44,6 +45,30 @@ static bool qtest_opened;
  *
  * Valid requests
  *
+ * Clock management:
+ *
+ * The qtest client is completely in charge of the vm_clock.  qtest commands
+ * let you adjust the value of the clock (monotonically).  All the commands
+ * return the current value of the clock in nanoseconds.
+ *
+ *  > clock_step
+ *  < OK VALUE
+ *
+ *     Advance the clock to the next deadline.  Useful when waiting for
+ *     asynchronous events.
+ *
+ *  > clock_step NS
+ *  < OK VALUE
+ *
+ *     Advance the clock by NS nanoseconds.
+ *
+ *  > clock_set NS
+ *  < OK VALUE
+ *
+ *     Advance the clock to NS nanoseconds (do nothing if it's already past).
+ *
+ * PIO and memory access:
+ *
  *  > outb ADDR VALUE
  *  < OK
  *
@@ -298,6 +323,25 @@ static void qtest_process_command(CharDriverState *chr, gchar **words)
 
         qtest_send_prefix(chr);
         qtest_send(chr, "OK\n");
+    } else if (strcmp(words[0], "clock_step") == 0) {
+        int64_t ns;
+
+        if (words[1]) {
+            ns = strtoll(words[1], NULL, 0);
+        } else {
+            ns = qemu_clock_deadline(vm_clock);
+        }
+        qtest_clock_warp(qemu_get_clock_ns(vm_clock) + ns);
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
+    } else if (strcmp(words[0], "clock_set") == 0) {
+        int64_t ns;
+
+        g_assert(words[1]);
+        ns = strtoll(words[1], NULL, 0);
+        qtest_clock_warp(ns);
+        qtest_send_prefix(chr);
+        qtest_send(chr, "OK %"PRIi64"\n", (int64_t)qemu_get_clock_ns(vm_clock));
     } else {
         qtest_send_prefix(chr);
         qtest_send(chr, "FAIL Unknown command `%s'\n", words[0]);
@@ -376,6 +420,7 @@ int qtest_init(void)
 
     g_assert(qtest_chrdev != NULL);
 
+    configure_icount("0");
     chr = qemu_chr_new("qtest", qtest_chrdev, NULL);
 
     qemu_chr_add_handlers(chr, qtest_can_read, qtest_read, qtest_event, chr);
-- 
1.7.7.1

      parent reply	other threads:[~2012-01-18 14:32 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-01-18 10:33 [Qemu-devel] [RFC PATCH 0/9] qtest fixes and alternative IRQ intercept proposal Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 1/9] qtest: always send a response Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 2/9] qtest: enable echo Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 3/9] qtest: fix Makefile Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 4/9] rtc-test: fix set_alarm_time Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 5/9] qtest: do not use TCG CPU threads Paolo Bonzini
2012-01-18 10:53   ` Andreas Färber
2012-01-18 11:14     ` Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 6/9] pc: attach ioapic to the QOM composition tree Paolo Bonzini
2012-01-24 15:12   ` Jan Kiszka
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 7/9] qtest: IRQ interception infrastructure Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 8/9] libqtest: add IRQ intercept commands Paolo Bonzini
2012-01-18 10:33 ` [Qemu-devel] [RFC PATCH 9/9] rtc-test: add IRQ intercept Paolo Bonzini
2012-01-18 14:31 ` Paolo Bonzini [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1326897107-16340-1-git-send-email-pbonzini@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).