4 * Copyright IBM, Corp. 2011
7 * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
8 * Kevin Wolf <kwolf@redhat.com>
10 * This work is licensed under the terms of the GNU LGPL, version 2 or later.
11 * See the COPYING.LIB file in the top-level directory.
16 #include "qemu-common.h"
17 #include "block/coroutine.h"
18 #include "block/coroutine_int.h"
21 /* Maximum free pool size prevents holding too many freed coroutines */
25 /** Free list to speed up creation */
26 static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool);
27 static unsigned int pool_size;
29 Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
33 co = QSLIST_FIRST(&pool);
35 QSLIST_REMOVE_HEAD(&pool, pool_next);
38 co = qemu_coroutine_new();
45 static void coroutine_delete(Coroutine *co)
47 if (pool_size < POOL_MAX_SIZE) {
48 QSLIST_INSERT_HEAD(&pool, co, pool_next);
54 qemu_coroutine_delete(co);
57 static void __attribute__((destructor)) coroutine_cleanup(void)
62 QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
63 QSLIST_REMOVE_HEAD(&pool, pool_next);
64 qemu_coroutine_delete(co);
68 static void coroutine_swap(Coroutine *from, Coroutine *to)
72 ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD);
77 case COROUTINE_TERMINATE:
78 trace_qemu_coroutine_terminate(to);
86 void qemu_coroutine_enter(Coroutine *co, void *opaque)
88 Coroutine *self = qemu_coroutine_self();
90 trace_qemu_coroutine_enter(self, co, opaque);
93 fprintf(stderr, "Co-routine re-entered recursively\n");
98 co->entry_arg = opaque;
99 coroutine_swap(self, co);
102 void coroutine_fn qemu_coroutine_yield(void)
104 Coroutine *self = qemu_coroutine_self();
105 Coroutine *to = self->caller;
107 trace_qemu_coroutine_yield(self, to);
110 fprintf(stderr, "Co-routine is yielding to no one\n");
115 coroutine_swap(self, to);