From patchwork Mon Jul 29 03:16:06 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: pingfan liu X-Patchwork-Id: 262653 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8D9272C0105 for ; Mon, 29 Jul 2013 13:18:26 +1000 (EST) Received: from localhost ([::1]:33621 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3dya-0001hp-F4 for incoming@patchwork.ozlabs.org; Sun, 28 Jul 2013 23:18:24 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:45016) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3dy6-0001Q1-5X for qemu-devel@nongnu.org; Sun, 28 Jul 2013 23:18:03 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V3dxx-0002Ld-Mw for qemu-devel@nongnu.org; Sun, 28 Jul 2013 23:17:54 -0400 Received: from mail-ob0-x22b.google.com ([2607:f8b0:4003:c01::22b]:39326) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V3dxx-0002LZ-IS for qemu-devel@nongnu.org; Sun, 28 Jul 2013 23:17:45 -0400 Received: by mail-ob0-f171.google.com with SMTP id tb18so8379913obb.30 for ; Sun, 28 Jul 2013 20:17:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; bh=tcEiQRfjD0k4S1V5B1JxHukXxTXeggyDHrdHQpNa2to=; b=sOCSdoq7BJDEI7UeS7y7/UTs5OjR6PCndzcNvrv5Qpi2YL7nE9e51t79ViCIVFlyFg T/rVAQx4QVavC93QMvXzfuuuvuwrLpfG9mQFcuJllBWuQyhpSIlZpuuqrgEoeIUdWdRU BfASnVk2jadES0uJNZcAH/wrQ9nl+kwEcM1Yikj3Kj+4ZtHEA3gcKPNMiucwXTYvzsvg 4tWq7WeV6sAj2HDANWzl1SR+YL8r+ntcXUfhYq+udH+hjSZOYMBEdSQjDzhb/80m6qX8 MGTg91muYo/kyc0mZrGGZFQxaCfqvb4k7X+REjm1N+pUY11UlvrcX3IbtxkYVo0q6Z8G 8rog== X-Received: by 10.182.18.71 with SMTP id u7mr50807074obd.100.1375067865051; Sun, 28 Jul 2013 20:17:45 -0700 (PDT) Received: from localhost ([202.108.130.138]) by mx.google.com with ESMTPSA id tv3sm85154303obb.8.2013.07.28.20.17.41 for (version=TLSv1.2 cipher=RC4-SHA bits=128/128); Sun, 28 Jul 2013 20:17:44 -0700 (PDT) From: Liu Ping Fan To: qemu-devel@nongnu.org Date: Mon, 29 Jul 2013 11:16:06 +0800 Message-Id: <1375067768-11342-4-git-send-email-pingfank@linux.vnet.ibm.com> X-Mailer: git-send-email 1.8.1.4 In-Reply-To: <1375067768-11342-1-git-send-email-pingfank@linux.vnet.ibm.com> References: <1375067768-11342-1-git-send-email-pingfank@linux.vnet.ibm.com> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2607:f8b0:4003:c01::22b Cc: Kevin Wolf , Stefan Hajnoczi , Jan Kiszka , Alex Bligh , Anthony Liguori , Paolo Bonzini Subject: [Qemu-devel] [RFC v2 3/5] timer: make qemu_clock_enable sync between disable and timer's cb 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 After disabling the QemuClock, we should make sure that no QemuTimers are still in flight. To implement that, the caller of disabling will wait until the last user's exit. Note, the callers of qemu_clock_enable() should be sync by themselves, not protected by this patch. Signed-off-by: Liu Ping Fan --- qemu-timer.c | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/qemu-timer.c b/qemu-timer.c index 5a42035..d941a83 100644 --- a/qemu-timer.c +++ b/qemu-timer.c @@ -60,6 +60,14 @@ struct QEMUClock { int type; bool enabled; + + /* rule: Innermost lock + * to protect the disable against timer's cb in flight. + */ + QemuMutex lock; + /* reference by timer list */ + int using; + QemuCond wait_using; }; struct QEMUTimer { @@ -274,6 +282,9 @@ static QEMUClock *qemu_new_clock(int type) clock->type = type; clock->enabled = true; clock->last = INT64_MIN; + clock->using = 0; + qemu_cond_init(&clock->wait_using); + qemu_mutex_init(&clock->lock); notifier_list_init(&clock->reset_notifiers); tlist = clock_to_timerlist(clock); timer_list_init(tlist); @@ -287,6 +298,13 @@ void qemu_clock_enable(QEMUClock *clock, bool enabled) clock->enabled = enabled; if (enabled && !old) { qemu_rearm_alarm_timer(alarm_timer); + } else { + qemu_mutex_lock(&clock->lock); + /* Wait for cb in flight to terminate */ + while (atomic_read(clock->using)) { + qemu_cond_wait(&clock->wait_using, &clock->lock); + } + qemu_mutex_unlock(&clock->lock); } } @@ -440,8 +458,11 @@ void qemu_run_timers(QEMUClock *clock) int64_t current_time; TimerList *tlist; - if (!clock->enabled) - return; + atomic_inc(&clock->using); + if (unlikely(!clock->enabled)) { + goto exit; + } + current_time = qemu_get_clock_ns(clock); tlist = clock_to_timerlist(clock); @@ -461,6 +482,15 @@ void qemu_run_timers(QEMUClock *clock) /* run the callback (the timer list can be modified) */ ts->cb(ts->opaque); } + +exit: + qemu_mutex_lock(&clock->lock); + if (atomic_fetch_dec(&clock->using) == 1) { + if (unlikely(!clock->enabled)) { + qemu_cond_signal(&clock->wait_using); + } + } + qemu_mutex_unlock(&clock->lock); } int64_t qemu_get_clock_ns(QEMUClock *clock)