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
);