diff options
author | Paolo Bonzini | 2017-02-13 14:52:19 +0100 |
---|---|---|
committer | Stefan Hajnoczi | 2017-02-21 12:14:07 +0100 |
commit | 0c330a734b51c177ab8488932ac3b0c4d63a718a (patch) | |
tree | 1251fc380ca5313495d9a9c541460b3ac2ffb7e0 /include/qemu | |
parent | block: move AioContext, QEMUTimer, main-loop to libqemuutil (diff) | |
download | qemu-0c330a734b51c177ab8488932ac3b0c4d63a718a.tar.gz qemu-0c330a734b51c177ab8488932ac3b0c4d63a718a.tar.xz qemu-0c330a734b51c177ab8488932ac3b0c4d63a718a.zip |
aio: introduce aio_co_schedule and aio_co_wake
aio_co_wake provides the infrastructure to start a coroutine on a "home"
AioContext. It will be used by CoMutex and CoQueue, so that coroutines
don't jump from one context to another when they go to sleep on a
mutex or waitqueue. However, it can also be used as a more efficient
alternative to one-shot bottom halves, and saves the effort of tracking
which AioContext a coroutine is running on.
aio_co_schedule is the part of aio_co_wake that starts a coroutine
on a remove AioContext, but it is also useful to implement e.g.
bdrv_set_aio_context callbacks.
The implementation of aio_co_schedule is based on a lock-free
multiple-producer, single-consumer queue. The multiple producers use
cmpxchg to add to a LIFO stack. The consumer (a per-AioContext bottom
half) grabs all items added so far, inverts the list to make it FIFO,
and goes through it one item at a time until it's empty. The data
structure was inspired by OSv, which uses it in the very code we'll
"port" to QEMU for the thread-safe CoMutex.
Most of the new code is really tests.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Fam Zheng <famz@redhat.com>
Message-id: 20170213135235.12274-3-pbonzini@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'include/qemu')
-rw-r--r-- | include/qemu/coroutine_int.h | 11 |
1 files changed, 10 insertions, 1 deletions
diff --git a/include/qemu/coroutine_int.h b/include/qemu/coroutine_int.h index 14d4f1d1f2..cb98892bba 100644 --- a/include/qemu/coroutine_int.h +++ b/include/qemu/coroutine_int.h @@ -40,12 +40,21 @@ struct Coroutine { CoroutineEntry *entry; void *entry_arg; Coroutine *caller; + + /* Only used when the coroutine has terminated. */ QSLIST_ENTRY(Coroutine) pool_next; + size_t locks_held; - /* Coroutines that should be woken up when we yield or terminate */ + /* Coroutines that should be woken up when we yield or terminate. + * Only used when the coroutine is running. + */ QSIMPLEQ_HEAD(, Coroutine) co_queue_wakeup; + + /* Only used when the coroutine has yielded. */ + AioContext *ctx; QSIMPLEQ_ENTRY(Coroutine) co_queue_next; + QSLIST_ENTRY(Coroutine) co_scheduled_next; }; Coroutine *qemu_coroutine_new(void); |