[sheepdog] [Qemu-devel] [PATCH v4 06/10] coroutine: add co_aio_sleep_ns() to allow sleep in block drivers
MORITA Kazutaka
morita.kazutaka at lab.ntt.co.jp
Fri Aug 2 08:20:40 CEST 2013
At Tue, 30 Jul 2013 15:58:58 +0200,
Stefan Hajnoczi wrote:
>
> 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 <morita.kazutaka at lab.ntt.co.jp>
> > ---
> > 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().
Okay, I'll update this patch based on the AioContext timer. I'm also
happy to help Alex and Pingfan to finish the implementation.
Thanks,
Kazutaka
More information about the sheepdog
mailing list