From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39047) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V4ASB-0006ty-MW for qemu-devel@nongnu.org; Tue, 30 Jul 2013 09:59:14 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1V4AS6-0006F4-Cy for qemu-devel@nongnu.org; Tue, 30 Jul 2013 09:59:07 -0400 Received: from mail-wi0-x229.google.com ([2a00:1450:400c:c05::229]:45167) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1V4AS6-0006Er-7Z for qemu-devel@nongnu.org; Tue, 30 Jul 2013 09:59:02 -0400 Received: by mail-wi0-f169.google.com with SMTP id f14so2150449wiw.4 for ; Tue, 30 Jul 2013 06:59:01 -0700 (PDT) Date: Tue, 30 Jul 2013 15:58:58 +0200 From: Stefan Hajnoczi Message-ID: <20130730135858.GC7471@stefanha-thinkpad.redhat.com> References: <1374819052-4292-1-git-send-email-morita.kazutaka@lab.ntt.co.jp> <1374819052-4292-7-git-send-email-morita.kazutaka@lab.ntt.co.jp> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1374819052-4292-7-git-send-email-morita.kazutaka@lab.ntt.co.jp> Subject: Re: [Qemu-devel] [PATCH v4 06/10] coroutine: add co_aio_sleep_ns() to allow sleep in block drivers List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: MORITA Kazutaka Cc: Kevin Wolf , pingfank@linux.vnet.ibm.com, sheepdog@lists.wpkg.org, alex@alex.org.uk, qemu-devel@nongnu.org, Stefan Hajnoczi , Liu Yuan , Paolo Bonzini On Fri, Jul 26, 2013 at 03:10:48PM +0900, MORITA Kazutaka wrote: > 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) { This breaks the Windows build and makes qemu_aio_wait() spin instead of blocking (wastes CPU). I think Alex Bligh and Ping Fan's QEMUTimer in AioContext work is needed here. I have CCed them. Their patches would allow you to use co_sleep_ns() in qemu_aio_wait(). > + 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); > +} > -- > 1.8.1.3.566.gaa39828 > >