mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
coroutine: protect global pool with a mutex
The coroutine freelist is a global pool of unused coroutines. It avoids the setup/teardown overhead associated with the coroutine lifecycle. Since the pool is global, we need to synchronize access so that coroutines can be used outside the BQL. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
bd91ecbf5b
commit
b84c458623
1 changed files with 18 additions and 2 deletions
|
@ -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,6 +24,7 @@ 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;
|
||||
|
||||
|
@ -30,11 +32,15 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
|
|||
{
|
||||
Coroutine *co;
|
||||
|
||||
qemu_mutex_lock(&pool_lock);
|
||||
co = QSLIST_FIRST(&pool);
|
||||
if (co) {
|
||||
QSLIST_REMOVE_HEAD(&pool, pool_next);
|
||||
pool_size--;
|
||||
} else {
|
||||
}
|
||||
qemu_mutex_unlock(&pool_lock);
|
||||
|
||||
if (!co) {
|
||||
co = qemu_coroutine_new();
|
||||
}
|
||||
|
||||
|
@ -44,17 +50,25 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
|
|||
|
||||
static void coroutine_delete(Coroutine *co)
|
||||
{
|
||||
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 +77,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)
|
||||
|
|
Loading…
Reference in a new issue