From patchwork Thu Aug 15 20:34:23 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alex Bligh X-Patchwork-Id: 267439 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 30E612C0215 for ; Fri, 16 Aug 2013 06:43:44 +1000 (EST) Received: from localhost ([::1]:55395 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VA4OT-0005uc-L2 for incoming@patchwork.ozlabs.org; Thu, 15 Aug 2013 16:43:41 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:50531) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VA4GE-0002od-9D for qemu-devel@nongnu.org; Thu, 15 Aug 2013 16:35:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VA4G4-0001I9-6N for qemu-devel@nongnu.org; Thu, 15 Aug 2013 16:35:10 -0400 Received: from mail.avalus.com ([2001:41c8:10:1dd::10]:36450) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VA4G3-0001Hi-Sp for qemu-devel@nongnu.org; Thu, 15 Aug 2013 16:35:00 -0400 Received: by mail.avalus.com (Postfix) with ESMTPSA id 1E1FEC561BA; Thu, 15 Aug 2013 21:34:59 +0100 (BST) From: Alex Bligh To: qemu-devel@nongnu.org Date: Thu, 15 Aug 2013 21:34:23 +0100 Message-Id: <1376598879-18976-16-git-send-email-alex@alex.org.uk> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1376598879-18976-1-git-send-email-alex@alex.org.uk> References: <1376598879-18976-1-git-send-email-alex@alex.org.uk> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:41c8:10:1dd::10 Cc: Kevin Wolf , Anthony Liguori , Alex Bligh , Jan Kiszka , liu ping fan , Stefan Hajnoczi , Paolo Bonzini , MORITA Kazutaka , rth@twiddle.net Subject: [Qemu-devel] [PATCHv11 15/31] aio / timers: Convert aio_poll to use AioContext timers' deadline 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 Convert aio_poll to use deadline based on AioContext's timers. aio_poll has been changed to return accurately whether progress has occurred. Prior to this commit, aio_poll always returned true if g_poll was entered, whether or not any progress was made. This required a change to tests/test-aio.c where an assert was backwards. Signed-off-by: Alex Bligh --- aio-posix.c | 20 +++++++++++++------- aio-win32.c | 22 +++++++++++++++++++--- tests/test-aio.c | 4 ++-- 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/aio-posix.c b/aio-posix.c index b68eccd..e5b89ab 100644 --- a/aio-posix.c +++ b/aio-posix.c @@ -166,6 +166,10 @@ static bool aio_dispatch(AioContext *ctx) g_free(tmp); } } + + /* Run our timers */ + progress |= timerlistgroup_run_timers(&ctx->tlg); + return progress; } @@ -232,9 +236,9 @@ bool aio_poll(AioContext *ctx, bool blocking) } /* wait until next event */ - ret = g_poll((GPollFD *)ctx->pollfds->data, - ctx->pollfds->len, - blocking ? -1 : 0); + ret = qemu_poll_ns((GPollFD *)ctx->pollfds->data, + ctx->pollfds->len, + blocking ? timerlistgroup_deadline_ns(&ctx->tlg) : 0); /* if we have any readable fds, dispatch event */ if (ret > 0) { @@ -245,11 +249,13 @@ bool aio_poll(AioContext *ctx, bool blocking) node->pfd.revents = pfd->revents; } } - if (aio_dispatch(ctx)) { - progress = true; - } + } + + /* Run dispatch even if there were no readable fds to run timers */ + if (aio_dispatch(ctx)) { + progress = true; } assert(progress || busy); - return true; + return progress; } diff --git a/aio-win32.c b/aio-win32.c index 38723bf..479b871 100644 --- a/aio-win32.c +++ b/aio-win32.c @@ -98,6 +98,7 @@ bool aio_poll(AioContext *ctx, bool blocking) HANDLE events[MAXIMUM_WAIT_OBJECTS + 1]; bool busy, progress; int count; + int timeout; progress = false; @@ -111,6 +112,9 @@ bool aio_poll(AioContext *ctx, bool blocking) progress = true; } + /* Run timers */ + progress |= timerlistgroup_run_timers(&ctx->tlg); + /* * Then dispatch any pending callbacks from the GSource. * @@ -174,8 +178,11 @@ bool aio_poll(AioContext *ctx, bool blocking) /* wait until next event */ while (count > 0) { - int timeout = blocking ? INFINITE : 0; - int ret = WaitForMultipleObjects(count, events, FALSE, timeout); + int ret; + + timeout = blocking ? + qemu_timeout_ns_to_ms(timerlistgroup_deadline_ns(&ctx->tlg)) : 0; + ret = WaitForMultipleObjects(count, events, FALSE, timeout); /* if we have any signaled events, dispatch event */ if ((DWORD) (ret - WAIT_OBJECT_0) >= count) { @@ -214,6 +221,15 @@ bool aio_poll(AioContext *ctx, bool blocking) events[ret - WAIT_OBJECT_0] = events[--count]; } + if (blocking) { + /* Run the timers a second time. We do this because otherwise aio_wait + * will not note progress - and will stop a drain early - if we have + * a timer that was not ready to run entering g_poll but is ready + * after g_poll. This will only do anything if a timer has expired. + */ + progress |= timerlistgroup_run_timers(ctx->timer_list); + } + assert(progress || busy); - return true; + return progress; } diff --git a/tests/test-aio.c b/tests/test-aio.c index 2d7ec4c..eedf7f8 100644 --- a/tests/test-aio.c +++ b/tests/test-aio.c @@ -316,13 +316,13 @@ static void test_wait_event_notifier_noflush(void) event_notifier_set(&data.e); g_assert(aio_poll(ctx, false)); g_assert_cmpint(data.n, ==, 1); - g_assert(aio_poll(ctx, false)); + g_assert(!aio_poll(ctx, false)); g_assert_cmpint(data.n, ==, 1); event_notifier_set(&data.e); g_assert(aio_poll(ctx, false)); g_assert_cmpint(data.n, ==, 2); - g_assert(aio_poll(ctx, false)); + g_assert(!aio_poll(ctx, false)); g_assert_cmpint(data.n, ==, 2); event_notifier_set(&dummy.e);