From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52919) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YQgOI-0002SU-LH for qemu-devel@nongnu.org; Wed, 25 Feb 2015 13:08:59 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YQgOH-0001hK-DC for qemu-devel@nongnu.org; Wed, 25 Feb 2015 13:08:58 -0500 From: Max Reitz Date: Wed, 25 Feb 2015 13:08:27 -0500 Message-Id: <1424887718-10800-15-git-send-email-mreitz@redhat.com> In-Reply-To: <1424887718-10800-1-git-send-email-mreitz@redhat.com> References: <1424887718-10800-1-git-send-email-mreitz@redhat.com> Subject: [Qemu-devel] [PATCH 14/25] coroutine: Add co_yield_timeout() List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-block@nongnu.org Cc: Kevin Wolf , Paolo Bonzini , qemu-devel@nongnu.org, Stefan Hajnoczi , Max Reitz Signed-off-by: Max Reitz --- include/block/coroutine.h | 6 ++++++ qemu-coroutine-sleep.c | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/include/block/coroutine.h b/include/block/coroutine.h index 20c027a..a05aefb 100644 --- a/include/block/coroutine.h +++ b/include/block/coroutine.h @@ -216,4 +216,10 @@ void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type, */ void coroutine_fn yield_until_fd_readable(int fd); +/** + * Yield with a timeout given in nanoseconds. Returns true if the timeout + * expired. + */ +bool coroutine_fn co_yield_timeout(QEMUClockType type, int64_t ns); + #endif /* QEMU_COROUTINE_H */ diff --git a/qemu-coroutine-sleep.c b/qemu-coroutine-sleep.c index 9abb7fd..9b33bf0 100644 --- a/qemu-coroutine-sleep.c +++ b/qemu-coroutine-sleep.c @@ -14,6 +14,7 @@ #include "block/coroutine.h" #include "qemu/timer.h" #include "block/aio.h" +#include "qemu/main-loop.h" typedef struct CoSleepCB { QEMUTimer *ts; @@ -39,3 +40,36 @@ void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type, timer_del(sleep_cb.ts); timer_free(sleep_cb.ts); } + +typedef struct CoTimeoutCB { + Coroutine *co; + bool expired; +} CoTimeoutCB; + +static void co_timeout_cb(void *opaque) +{ + CoTimeoutCB *timeout_cb = opaque; + + timeout_cb->expired = true; + qemu_coroutine_enter(timeout_cb->co, NULL); +} + +bool coroutine_fn co_yield_timeout(QEMUClockType type, int64_t ns) +{ + QEMUTimer timer; + CoTimeoutCB timeout_cb = { + .co = qemu_coroutine_self() + }; + + if (!ns) { + return true; + } + + aio_timer_init(qemu_get_aio_context(), &timer, type, SCALE_NS, + &co_timeout_cb, &timeout_cb); + timer_mod(&timer, qemu_clock_get_ns(type) + ns); + qemu_coroutine_yield(); + timer_del(&timer); + + return timeout_cb.expired; +} -- 2.1.0