From patchwork Mon Dec 21 08:09:22 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 41528 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id ADD7FB6F08 for ; Mon, 21 Dec 2009 19:52:15 +1100 (EST) Received: from localhost ([127.0.0.1]:45154 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NMdzv-00059J-Hw for incoming@patchwork.ozlabs.org; Mon, 21 Dec 2009 03:52:11 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NMdKx-0002mX-0O for qemu-devel@nongnu.org; Mon, 21 Dec 2009 03:09:51 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NMdKq-0002ik-OI for qemu-devel@nongnu.org; Mon, 21 Dec 2009 03:09:48 -0500 Received: from [199.232.76.173] (port=52820 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NMdKp-0002ig-Oi for qemu-devel@nongnu.org; Mon, 21 Dec 2009 03:09:43 -0500 Received: from mx1.redhat.com ([209.132.183.28]:65292) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NMdKp-0003oo-6z for qemu-devel@nongnu.org; Mon, 21 Dec 2009 03:09:43 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nBL89gPV029836 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 21 Dec 2009 03:09:42 -0500 Received: from localhost.localdomain (vpn2-10-119.ams2.redhat.com [10.36.10.119]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id nBL89V3V011460 for ; Mon, 21 Dec 2009 03:09:41 -0500 From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Mon, 21 Dec 2009 09:09:22 +0100 Message-Id: <1261382970-23251-12-git-send-email-pbonzini@redhat.com> In-Reply-To: <1261382970-23251-1-git-send-email-pbonzini@redhat.com> References: <1261382970-23251-1-git-send-email-pbonzini@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Subject: [Qemu-devel] [PATCH 11/19] use a bottom half to run timers X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Make the timer subsystem register its own bottom half instead of placing the bottom half code in the heart of the main loop. To test if an alarm timer is pending, just check if the bottom half is scheduled. Signed-off-by: Paolo Bonzini --- vl.c | 68 ++++++++++++++++++++++++++++++++++++----------------------------- 1 files changed, 38 insertions(+), 30 deletions(-) diff --git a/vl.c b/vl.c index 78807f5..289aadc 100644 --- a/vl.c +++ b/vl.c @@ -573,10 +573,17 @@ struct qemu_alarm_timer { void (*rearm)(struct qemu_alarm_timer *t); void *priv; + QEMUBH *bh; char expired; - char pending; }; +static struct qemu_alarm_timer *alarm_timer; + +static inline int qemu_alarm_pending(void) +{ + return qemu_bh_scheduled(alarm_timer->bh); +} + static inline int alarm_has_dynticks(struct qemu_alarm_timer *t) { return !!t->rearm; @@ -593,8 +600,6 @@ static void qemu_rearm_alarm_timer(struct qemu_alarm_timer *t) /* TODO: MIN_TIMER_REARM_US should be optimized */ #define MIN_TIMER_REARM_US 250 -static struct qemu_alarm_timer *alarm_timer; - #ifdef _WIN32 struct qemu_alarm_win32 { @@ -874,7 +879,7 @@ void qemu_mod_timer(QEMUTimer *ts, int64_t expire_time) /* Rearm if necessary */ if (pt == &active_timers[ts->clock->type]) { - if (!alarm_timer->pending) { + if (!qemu_alarm_pending()) { qemu_rearm_alarm_timer(alarm_timer); } /* Interrupt execution to force deadline recalculation. */ @@ -1001,6 +1006,31 @@ static const VMStateDescription vmstate_timers = { static void qemu_event_increment(void); +static void qemu_timer_bh(void *opaque) +{ + struct qemu_alarm_timer *t = opaque; + + /* rearm timer, if not periodic */ + if (t->expired) { + t->expired = 0; + qemu_rearm_alarm_timer(t); + } + + /* vm time timers */ + if (vm_running) { + if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER))) + qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL], + qemu_get_clock(vm_clock)); + } + + /* real time timers */ + qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME], + qemu_get_clock(rt_clock)); + + qemu_run_timers(&active_timers[QEMU_CLOCK_HOST], + qemu_get_clock(host_clock)); +} + #ifdef _WIN32 static void CALLBACK host_alarm_handler(UINT uTimerID, UINT uMsg, DWORD_PTR dwUser, DWORD_PTR dw1, @@ -1059,8 +1089,7 @@ static void host_alarm_handler(int host_signum) cpu_exit(next_cpu); } #endif - t->pending = 1; - qemu_notify_event(); + qemu_bh_schedule(t->bh); } } @@ -1446,7 +1475,8 @@ static int init_timer_alarm(void) } /* first event is at time 0 */ - t->pending = 1; + t->bh = qemu_bh_new(qemu_timer_bh, t); + qemu_bh_schedule(t->bh); alarm_timer = t; qemu_add_vm_change_state_handler(alarm_timer_on_change_state_rearm, t); @@ -3811,28 +3841,6 @@ void main_loop_wait(int timeout) slirp_select_poll(&rfds, &wfds, &xfds, (ret < 0)); - /* rearm timer, if not periodic */ - if (alarm_timer->expired) { - alarm_timer->expired = 0; - qemu_rearm_alarm_timer(alarm_timer); - } - - alarm_timer->pending = 0; - - /* vm time timers */ - if (vm_running) { - if (!cur_cpu || likely(!(cur_cpu->singlestep_enabled & SSTEP_NOTIMER))) - qemu_run_timers(&active_timers[QEMU_CLOCK_VIRTUAL], - qemu_get_clock(vm_clock)); - } - - /* real time timers */ - qemu_run_timers(&active_timers[QEMU_CLOCK_REALTIME], - qemu_get_clock(rt_clock)); - - qemu_run_timers(&active_timers[QEMU_CLOCK_HOST], - qemu_get_clock(host_clock)); - /* Check bottom-halves last in case any of the earlier events triggered them. */ qemu_bh_poll(); @@ -3888,7 +3896,7 @@ static void tcg_cpu_exec(void) if (!vm_running) break; - if (alarm_timer->pending) + if (qemu_alarm_pending()) break; if (cpu_can_run(env)) ret = qemu_cpu_exec(env);