X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=qemu-coroutine.c;h=470852100af1eb58e69f44d91cf29a11df7cff93;hb=8d07d6c46597a885eb38d99cc6fff399ce69cd21;hp=25a14c605db5acea79ded776b33153d039725e43;hpb=ee24aaf356f44ca7c8fbef136a438c12091cffd0;p=qemu.git diff --git a/qemu-coroutine.c b/qemu-coroutine.c index 25a14c605..470852100 100644 --- a/qemu-coroutine.c +++ b/qemu-coroutine.c @@ -14,6 +14,7 @@ #include "trace.h" #include "qemu-common.h" +#include "qemu/thread.h" #include "block/coroutine.h" #include "block/coroutine_int.h" @@ -23,38 +24,56 @@ enum { }; /** Free list to speed up creation */ +static QemuMutex pool_lock; static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool); static unsigned int pool_size; Coroutine *qemu_coroutine_create(CoroutineEntry *entry) { - Coroutine *co; + Coroutine *co = NULL; + + if (CONFIG_COROUTINE_POOL) { + qemu_mutex_lock(&pool_lock); + co = QSLIST_FIRST(&pool); + if (co) { + QSLIST_REMOVE_HEAD(&pool, pool_next); + pool_size--; + } + qemu_mutex_unlock(&pool_lock); + } - co = QSLIST_FIRST(&pool); - if (co) { - QSLIST_REMOVE_HEAD(&pool, pool_next); - pool_size--; - } else { + if (!co) { co = qemu_coroutine_new(); } co->entry = entry; + QTAILQ_INIT(&co->co_queue_wakeup); 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; + if (CONFIG_COROUTINE_POOL) { + qemu_mutex_lock(&pool_lock); + if (pool_size < POOL_MAX_SIZE) { + QSLIST_INSERT_HEAD(&pool, co, pool_next); + co->caller = NULL; + pool_size++; + qemu_mutex_unlock(&pool_lock); + return; + } + qemu_mutex_unlock(&pool_lock); } qemu_coroutine_delete(co); } -static void __attribute__((destructor)) coroutine_cleanup(void) +static void __attribute__((constructor)) coroutine_pool_init(void) +{ + qemu_mutex_init(&pool_lock); +} + +static void __attribute__((destructor)) coroutine_pool_cleanup(void) { Coroutine *co; Coroutine *tmp; @@ -63,6 +82,8 @@ static void __attribute__((destructor)) coroutine_cleanup(void) QSLIST_REMOVE_HEAD(&pool, pool_next); qemu_coroutine_delete(co); } + + qemu_mutex_destroy(&pool_lock); } static void coroutine_swap(Coroutine *from, Coroutine *to) @@ -71,6 +92,8 @@ static void coroutine_swap(Coroutine *from, Coroutine *to) ret = qemu_coroutine_switch(from, to, COROUTINE_YIELD); + qemu_co_queue_run_restart(to); + switch (ret) { case COROUTINE_YIELD: return;