From patchwork Thu Mar 15 13:37:46 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anthony Liguori X-Patchwork-Id: 146971 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 039E9B6EE6 for ; Fri, 16 Mar 2012 00:57:24 +1100 (EST) Received: from localhost ([::1]:36274 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8AuQ-0002e5-7D for incoming@patchwork.ozlabs.org; Thu, 15 Mar 2012 09:40:02 -0400 Received: from eggs.gnu.org ([208.118.235.92]:57520) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8AuD-0002EU-Ek for qemu-devel@nongnu.org; Thu, 15 Mar 2012 09:39:51 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1S8Au4-00063Q-7r for qemu-devel@nongnu.org; Thu, 15 Mar 2012 09:39:49 -0400 Received: from e34.co.us.ibm.com ([32.97.110.152]:54397) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1S8Au4-00062g-1E for qemu-devel@nongnu.org; Thu, 15 Mar 2012 09:39:40 -0400 Received: from /spool/local by e34.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Thu, 15 Mar 2012 07:39:33 -0600 Received: from d03dlp01.boulder.ibm.com (9.17.202.177) by e34.co.us.ibm.com (192.168.1.134) with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted; Thu, 15 Mar 2012 07:38:31 -0600 Received: from d03relay01.boulder.ibm.com (d03relay01.boulder.ibm.com [9.17.195.226]) by d03dlp01.boulder.ibm.com (Postfix) with ESMTP id 878E9C40007 for ; Thu, 15 Mar 2012 07:38:29 -0600 (MDT) Received: from d03av05.boulder.ibm.com (d03av05.boulder.ibm.com [9.17.195.85]) by d03relay01.boulder.ibm.com (8.13.8/8.13.8/NCO v10.0) with ESMTP id q2FDc6tY209152 for ; Thu, 15 Mar 2012 07:38:09 -0600 Received: from d03av05.boulder.ibm.com (loopback [127.0.0.1]) by d03av05.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVout) with ESMTP id q2FDc519029116 for ; Thu, 15 Mar 2012 07:38:05 -0600 Received: from titi.austin.rr.com (sig-9-65-116-158.mts.ibm.com [9.65.116.158]) by d03av05.boulder.ibm.com (8.14.4/8.13.1/NCO v10.0 AVin) with ESMTP id q2FDbpER028311; Thu, 15 Mar 2012 07:38:04 -0600 From: Anthony Liguori To: qemu-devel@nongnu.org Date: Thu, 15 Mar 2012 08:37:46 -0500 Message-Id: <1331818666-31718-10-git-send-email-aliguori@us.ibm.com> X-Mailer: git-send-email 1.7.5.4 In-Reply-To: <1331818666-31718-1-git-send-email-aliguori@us.ibm.com> References: <1331818666-31718-1-git-send-email-aliguori@us.ibm.com> X-Content-Scanned: Fidelis XPS MAILER x-cbid: 12031513-1780-0000-0000-000003FC4F7D X-IBM-ISS-SpamDetectors: X-IBM-ISS-DetailInfo: BY=3.00000256; HX=3.00000185; KW=3.00000007; PH=3.00000001; SC=3.00000001; SDB=6.00122236; UDB=6.00029410; UTC=2012-03-15 13:39:31 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 32.97.110.152 Cc: Paolo Bonzini , Anthony Liguori Subject: [Qemu-devel] [PATCH 9/9] qtest: add clock management X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Paolo Bonzini 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 Signed-off-by: Anthony Liguori --- 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 010047e..107b2ca 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..81bd817 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 d7f56e5..80bcc56 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 a1eca49..53e2b79 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 * @@ -299,6 +324,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]); @@ -377,6 +421,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);