提交 b84c4586 编写于 作者: S Stefan Hajnoczi

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: NStefan Hajnoczi <stefanha@redhat.com>
上级 bd91ecbf
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "trace.h" #include "trace.h"
#include "qemu-common.h" #include "qemu-common.h"
#include "qemu/thread.h"
#include "block/coroutine.h" #include "block/coroutine.h"
#include "block/coroutine_int.h" #include "block/coroutine_int.h"
...@@ -23,6 +24,7 @@ enum { ...@@ -23,6 +24,7 @@ enum {
}; };
/** Free list to speed up creation */ /** Free list to speed up creation */
static QemuMutex pool_lock;
static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool); static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool);
static unsigned int pool_size; static unsigned int pool_size;
...@@ -30,11 +32,15 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry) ...@@ -30,11 +32,15 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
{ {
Coroutine *co; Coroutine *co;
qemu_mutex_lock(&pool_lock);
co = QSLIST_FIRST(&pool); co = QSLIST_FIRST(&pool);
if (co) { if (co) {
QSLIST_REMOVE_HEAD(&pool, pool_next); QSLIST_REMOVE_HEAD(&pool, pool_next);
pool_size--; pool_size--;
} else { }
qemu_mutex_unlock(&pool_lock);
if (!co) {
co = qemu_coroutine_new(); co = qemu_coroutine_new();
} }
...@@ -44,17 +50,25 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry) ...@@ -44,17 +50,25 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
static void coroutine_delete(Coroutine *co) static void coroutine_delete(Coroutine *co)
{ {
qemu_mutex_lock(&pool_lock);
if (pool_size < POOL_MAX_SIZE) { if (pool_size < POOL_MAX_SIZE) {
QSLIST_INSERT_HEAD(&pool, co, pool_next); QSLIST_INSERT_HEAD(&pool, co, pool_next);
co->caller = NULL; co->caller = NULL;
pool_size++; pool_size++;
qemu_mutex_unlock(&pool_lock);
return; return;
} }
qemu_mutex_unlock(&pool_lock);
qemu_coroutine_delete(co); 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 *co;
Coroutine *tmp; Coroutine *tmp;
...@@ -63,6 +77,8 @@ static void __attribute__((destructor)) coroutine_cleanup(void) ...@@ -63,6 +77,8 @@ static void __attribute__((destructor)) coroutine_cleanup(void)
QSLIST_REMOVE_HEAD(&pool, pool_next); QSLIST_REMOVE_HEAD(&pool, pool_next);
qemu_coroutine_delete(co); qemu_coroutine_delete(co);
} }
qemu_mutex_destroy(&pool_lock);
} }
static void coroutine_swap(Coroutine *from, Coroutine *to) static void coroutine_swap(Coroutine *from, Coroutine *to)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册