From patchwork Wed Jul 24 07:56:30 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: MORITA Kazutaka X-Patchwork-Id: 261342 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 4BA082C0096 for ; Wed, 24 Jul 2013 18:23:07 +1000 (EST) Received: from localhost ([::1]:43060 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1u0Y-0004Gb-A7 for incoming@patchwork.ozlabs.org; Wed, 24 Jul 2013 04:01:14 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:36113) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1ty8-0000bz-NP for qemu-devel@nongnu.org; Wed, 24 Jul 2013 03:58:45 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V1ty7-0000hW-BC for qemu-devel@nongnu.org; Wed, 24 Jul 2013 03:58:44 -0400 Received: from sh.osrg.net ([192.16.179.4]:38802) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V1ty6-0000h0-Nr for qemu-devel@nongnu.org; Wed, 24 Jul 2013 03:58:43 -0400 Received: from fs.osrg.net (localns.osrg.net [10.0.0.11]) by sh.osrg.net (8.14.4/8.14.4/OSRG-NET) with ESMTP id r6O7wQi7014978; Wed, 24 Jul 2013 16:58:27 +0900 Received: from localhost (unknown [10.32.32.72]) by fs.osrg.net (Postfix) with ESMTP id 2C3EBF94D; Wed, 24 Jul 2013 16:58:25 +0900 (JST) From: MORITA Kazutaka To: Kevin Wolf , Stefan Hajnoczi , Paolo Bonzini , qemu-devel@nongnu.org Date: Wed, 24 Jul 2013 16:56:30 +0900 Message-Id: <1374652593-7242-7-git-send-email-morita.kazutaka@lab.ntt.co.jp> X-Mailer: git-send-email 1.8.1.3.566.gaa39828 In-Reply-To: <1374652593-7242-1-git-send-email-morita.kazutaka@lab.ntt.co.jp> References: <1374652593-7242-1-git-send-email-morita.kazutaka@lab.ntt.co.jp> X-Dispatcher: imput version 20100215(IM150) Lines: 93 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.3.9 (sh.osrg.net [192.16.179.4]); Wed, 24 Jul 2013 16:58:27 +0900 (JST) X-Virus-Scanned: clamav-milter 0.97.8 at sh X-Virus-Status: Clean X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 192.16.179.4 Cc: sheepdog@lists.wpkg.org Subject: [Qemu-devel] [PATCH v2 6/9] coroutine: add co_aio_sleep_ns() to allow sleep in block drivers 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 This helper function behaves similarly to co_sleep_ns(), but the sleeping coroutine will be resumed when using qemu_aio_wait(). Signed-off-by: MORITA Kazutaka --- include/block/coroutine.h | 8 ++++++++ qemu-coroutine-sleep.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/include/block/coroutine.h b/include/block/coroutine.h index 377805a..23ea6e9 100644 --- a/include/block/coroutine.h +++ b/include/block/coroutine.h @@ -210,6 +210,14 @@ void qemu_co_rwlock_unlock(CoRwlock *lock); void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns); /** + * Yield the coroutine for a given duration + * + * Behaves similarly to co_sleep_ns(), but the sleeping coroutine will be + * resumed when using qemu_aio_wait(). + */ +void coroutine_fn co_aio_sleep_ns(int64_t ns); + +/** * Yield until a file descriptor becomes readable * * Note that this function clobbers the handlers for the file descriptor. diff --git a/qemu-coroutine-sleep.c b/qemu-coroutine-sleep.c index 169ce5c..3955347 100644 --- a/qemu-coroutine-sleep.c +++ b/qemu-coroutine-sleep.c @@ -13,6 +13,7 @@ #include "block/coroutine.h" #include "qemu/timer.h" +#include "qemu/thread.h" typedef struct CoSleepCB { QEMUTimer *ts; @@ -37,3 +38,49 @@ void coroutine_fn co_sleep_ns(QEMUClock *clock, int64_t ns) qemu_del_timer(sleep_cb.ts); qemu_free_timer(sleep_cb.ts); } + +typedef struct CoAioSleepCB { + QEMUBH *bh; + int64_t ns; + Coroutine *co; +} CoAioSleepCB; + +static void co_aio_sleep_cb(void *opaque) +{ + CoAioSleepCB *aio_sleep_cb = opaque; + + qemu_coroutine_enter(aio_sleep_cb->co, NULL); +} + +static void *sleep_thread(void *opaque) +{ + CoAioSleepCB *aio_sleep_cb = opaque; + struct timespec req = { + .tv_sec = aio_sleep_cb->ns / 1000000000, + .tv_nsec = aio_sleep_cb->ns % 1000000000, + }; + struct timespec rem; + + while (nanosleep(&req, &rem) < 0 && errno == EINTR) { + req = rem; + } + + qemu_bh_schedule(aio_sleep_cb->bh); + + return NULL; +} + +void coroutine_fn co_aio_sleep_ns(int64_t ns) +{ + CoAioSleepCB aio_sleep_cb = { + .ns = ns, + .co = qemu_coroutine_self(), + }; + QemuThread thread; + + aio_sleep_cb.bh = qemu_bh_new(co_aio_sleep_cb, &aio_sleep_cb); + qemu_thread_create(&thread, sleep_thread, &aio_sleep_cb, + QEMU_THREAD_DETACHED); + qemu_coroutine_yield(); + qemu_bh_delete(aio_sleep_cb.bh); +}