and save 8 bytes for each coroutine.
--
Roman
@@ -65,10 +65,13 @@ typedef void coroutine_fn CoroutineEntry(void *opaque);
*/
Coroutine *qemu_coroutine_create(CoroutineEntry *entry, void *opaque);
+typedef QSIMPLEQ_HEAD(CoroutineQueue, Coroutine) CoroutineQueue;
+
/**
* Transfer control to a coroutine
*/
void qemu_coroutine_enter(Coroutine *coroutine);
+void __qemu_coroutine_enter(Coroutine *coroutine, CoroutineQueue
*queue_wakeup);
/**
* Transfer control back to a coroutine's caller
@@ -41,7 +41,7 @@ struct Coroutine {
QSLIST_ENTRY(Coroutine) pool_next;
/* Coroutines that should be woken up when we yield or terminate */
- QSIMPLEQ_HEAD(, Coroutine) co_queue_wakeup;
+ CoroutineQueue *co_queue_wakeup;
QSIMPLEQ_ENTRY(Coroutine) co_queue_next;
};
@@ -49,6 +49,6 @@ Coroutine *qemu_coroutine_new(void);
void qemu_coroutine_delete(Coroutine *co);
CoroutineAction qemu_coroutine_switch(Coroutine *from, Coroutine *to,
CoroutineAction action);
-void coroutine_fn qemu_co_queue_run_restart(Coroutine *co);
+void coroutine_fn qemu_co_queue_run_restart(CoroutineQueue *queue_wakeup);
#endif
@@ -50,27 +50,13 @@ void coroutine_fn qemu_co_queue_wait(CoQueue *queue)
* invoked by the core coroutine code when the current coroutine yields or
* terminates.
*/
-void qemu_co_queue_run_restart(Coroutine *co)
+void qemu_co_queue_run_restart(CoroutineQueue *queue_wakeup)
{
Coroutine *next;
- QSIMPLEQ_HEAD(, Coroutine) tmp_queue_wakeup =
- QSIMPLEQ_HEAD_INITIALIZER(tmp_queue_wakeup);
-
- trace_qemu_co_queue_run_restart(co);
-
- /*
- * We use temporal queue in order not to touch 'co' after entering
- * 'next' coroutine. The thing is that 'next' coroutine can resume
- * current 'co' coroutine and eventually terminate (free) it (see
- * linux-aio.c: ioq_submit() where qemu_laio_process_completions()
- * is invoked). The rule of thumb is simple: do not touch coroutine
- * when you enter another one.
- */
- QSIMPLEQ_CONCAT(&tmp_queue_wakeup, &co->co_queue_wakeup);
-
- while ((next = QSIMPLEQ_FIRST(&tmp_queue_wakeup))) {
- QSIMPLEQ_REMOVE_HEAD(&tmp_queue_wakeup, co_queue_next);
- qemu_coroutine_enter(next);
+
+ while ((next = QSIMPLEQ_FIRST(queue_wakeup))) {
+ QSIMPLEQ_REMOVE_HEAD(queue_wakeup, co_queue_next);
+ __qemu_coroutine_enter(next, queue_wakeup);
}
}
@@ -85,7 +71,7 @@ static bool qemu_co_queue_do_restart(CoQueue *queue,
bool single)
while ((next = QSIMPLEQ_FIRST(&queue->entries)) != NULL) {
QSIMPLEQ_REMOVE_HEAD(&queue->entries, co_queue_next);
- QSIMPLEQ_INSERT_TAIL(&self->co_queue_wakeup, next, co_queue_next);
+ QSIMPLEQ_INSERT_TAIL(self->co_queue_wakeup, next, co_queue_next);
trace_qemu_co_queue_next(next);
if (single) {
break;
@@ -77,7 +77,7 @@ Coroutine *qemu_coroutine_create(CoroutineEntry
*entry, void *opaque)
co->entry = entry;
co->entry_arg = opaque;
- QSIMPLEQ_INIT(&co->co_queue_wakeup);
+ co->co_queue_wakeup = NULL;
return co;
}