Allow using QemuCoSleep to sleep forever until woken by qemu_co_sleep_wake. This makes the logic of qemu_co_sleep_ns_wakeable easy to understand.
In the future we could introduce an API that can work even if the sleep and wake happen from different threads. For now, initializing w->to_wake after timer_mod is fine because the timer can only fire in the same AioContext. Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> --- include/qemu/coroutine.h | 5 +++++ util/qemu-coroutine-sleep.c | 20 +++++++++++++------- 2 files changed, 18 insertions(+), 7 deletions(-) diff --git a/include/qemu/coroutine.h b/include/qemu/coroutine.h index 77cb8ce459..b53e9632b9 100644 --- a/include/qemu/coroutine.h +++ b/include/qemu/coroutine.h @@ -302,6 +302,11 @@ typedef struct QemuCoSleep { void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w, QEMUClockType type, int64_t ns); +/** + * Yield the coroutine until the next call to qemu_co_sleep_wake. + */ +void coroutine_fn qemu_co_sleep(QemuCoSleep *w); + static inline void coroutine_fn qemu_co_sleep_ns(QEMUClockType type, int64_t ns) { QemuCoSleep w = { 0 }; diff --git a/util/qemu-coroutine-sleep.c b/util/qemu-coroutine-sleep.c index 89c3b758c5..df6edba2e4 100644 --- a/util/qemu-coroutine-sleep.c +++ b/util/qemu-coroutine-sleep.c @@ -41,12 +41,9 @@ static void co_sleep_cb(void *opaque) qemu_co_sleep_wake(w); } -void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w, - QEMUClockType type, int64_t ns) +void coroutine_fn qemu_co_sleep(QemuCoSleep *w) { Coroutine *co = qemu_coroutine_self(); - AioContext *ctx = qemu_get_current_aio_context(); - QEMUTimer ts; const char *scheduled = qatomic_cmpxchg(&co->scheduled, NULL, qemu_co_sleep_ns__scheduled); @@ -58,11 +55,20 @@ void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w, } w->to_wake = co; - aio_timer_init(ctx, &ts, type, SCALE_NS, co_sleep_cb, w), - timer_mod(&ts, qemu_clock_get_ns(type) + ns); qemu_coroutine_yield(); - timer_del(&ts); /* w->to_wake is cleared before resuming this coroutine. */ assert(w->to_wake == NULL); } + +void coroutine_fn qemu_co_sleep_ns_wakeable(QemuCoSleep *w, + QEMUClockType type, int64_t ns) +{ + AioContext *ctx = qemu_get_current_aio_context(); + QEMUTimer ts; + + aio_timer_init(ctx, &ts, type, SCALE_NS, co_sleep_cb, w); + timer_mod(&ts, qemu_clock_get_ns(type) + ns); + qemu_co_sleep(w); + timer_del(&ts); +} -- 2.31.1