Skip to content

Commit

Permalink
coroutine: add flag to re-queue at front of CoQueue
Browse files Browse the repository at this point in the history
When a coroutine wakes up it may determine that it must re-queue.
Normally coroutines are pushed onto the back of the CoQueue, but for
fairness it may be necessary to push it onto the front of the CoQueue.

Add a flag to specify that the coroutine should be pushed onto the front
of the CoQueue. A later patch will use this to ensure fairness in the
bounce buffer CoQueue used by the blkio BlockDriver.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Message-id: 20221013185908.1297568-2-stefanha@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
  • Loading branch information
stefanhaRH committed Oct 26, 2022
1 parent 79fc2fb commit 0421b56
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 4 deletions.
15 changes: 13 additions & 2 deletions include/qemu/coroutine.h
Expand Up @@ -198,14 +198,25 @@ typedef struct CoQueue {
*/
void qemu_co_queue_init(CoQueue *queue);

typedef enum {
/*
* Enqueue at front instead of back. Use this to re-queue a request when
* its wait condition is not satisfied after being woken up.
*/
CO_QUEUE_WAIT_FRONT = 0x1,
} CoQueueWaitFlags;

/**
* Adds the current coroutine to the CoQueue and transfers control to the
* caller of the coroutine. The mutex is unlocked during the wait and
* locked again afterwards.
*/
#define qemu_co_queue_wait(queue, lock) \
qemu_co_queue_wait_impl(queue, QEMU_MAKE_LOCKABLE(lock))
void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock);
qemu_co_queue_wait_impl(queue, QEMU_MAKE_LOCKABLE(lock), 0)
#define qemu_co_queue_wait_flags(queue, lock, flags) \
qemu_co_queue_wait_impl(queue, QEMU_MAKE_LOCKABLE(lock), (flags))
void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock,
CoQueueWaitFlags flags);

/**
* Removes the next coroutine from the CoQueue, and queue it to run after
Expand Down
9 changes: 7 additions & 2 deletions util/qemu-coroutine-lock.c
Expand Up @@ -39,10 +39,15 @@ void qemu_co_queue_init(CoQueue *queue)
QSIMPLEQ_INIT(&queue->entries);
}

void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock)
void coroutine_fn qemu_co_queue_wait_impl(CoQueue *queue, QemuLockable *lock,
CoQueueWaitFlags flags)
{
Coroutine *self = qemu_coroutine_self();
QSIMPLEQ_INSERT_TAIL(&queue->entries, self, co_queue_next);
if (flags & CO_QUEUE_WAIT_FRONT) {
QSIMPLEQ_INSERT_HEAD(&queue->entries, self, co_queue_next);
} else {
QSIMPLEQ_INSERT_TAIL(&queue->entries, self, co_queue_next);
}

if (lock) {
qemu_lockable_unlock(lock);
Expand Down

0 comments on commit 0421b56

Please sign in to comment.