diff options
Diffstat (limited to 'qemu-coroutine.c')
-rw-r--r-- | qemu-coroutine.c | 45 |
1 files changed, 43 insertions, 2 deletions
diff --git a/qemu-coroutine.c b/qemu-coroutine.c index 0f6e268574..25a14c605d 100644 --- a/qemu-coroutine.c +++ b/qemu-coroutine.c @@ -17,13 +17,54 @@ #include "block/coroutine.h" #include "block/coroutine_int.h" +enum { + /* Maximum free pool size prevents holding too many freed coroutines */ + POOL_MAX_SIZE = 64, +}; + +/** Free list to speed up creation */ +static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool); +static unsigned int pool_size; + Coroutine *qemu_coroutine_create(CoroutineEntry *entry) { - Coroutine *co = qemu_coroutine_new(); + Coroutine *co; + + co = QSLIST_FIRST(&pool); + if (co) { + QSLIST_REMOVE_HEAD(&pool, pool_next); + pool_size--; + } else { + co = qemu_coroutine_new(); + } + co->entry = entry; return co; } +static void coroutine_delete(Coroutine *co) +{ + if (pool_size < POOL_MAX_SIZE) { + QSLIST_INSERT_HEAD(&pool, co, pool_next); + co->caller = NULL; + pool_size++; + return; + } + + qemu_coroutine_delete(co); +} + +static void __attribute__((destructor)) coroutine_cleanup(void) +{ + Coroutine *co; + Coroutine *tmp; + + QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) { + QSLIST_REMOVE_HEAD(&pool, pool_next); + qemu_coroutine_delete(co); + } +} + static void coroutine_swap(Coroutine *from, Coroutine *to) { CoroutineAction ret; @@ -35,7 +76,7 @@ static void coroutine_swap(Coroutine *from, Coroutine *to) return; case COROUTINE_TERMINATE: trace_qemu_coroutine_terminate(to); - qemu_coroutine_delete(to); + coroutine_delete(to); return; default: abort(); |