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.kazut...@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(). > + 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 > >