[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for t
From: |
Peter Lieven |
Subject: |
[Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool |
Date: |
Thu, 27 Nov 2014 11:27:06 +0100 |
This patch creates a ring structure for the coroutine pool instead
of a linked list. The implementation of the list has the issue
that it always throws aways the latest coroutines instead of the
oldest ones. This is a drawback since the latest used coroutines
are more likely cached than old ones.
Furthermore this patch creates a coroutine pool per thread
to remove the need for locking.
Signed-off-by: Peter Lieven <address@hidden>
---
include/block/coroutine.h | 2 +-
iothread.c | 3 +++
qemu-coroutine.c | 54 ++++++++++++++++++++-------------------------
3 files changed, 28 insertions(+), 31 deletions(-)
diff --git a/include/block/coroutine.h b/include/block/coroutine.h
index 1d9343d..f0b3a2d 100644
--- a/include/block/coroutine.h
+++ b/include/block/coroutine.h
@@ -96,7 +96,7 @@ Coroutine *coroutine_fn qemu_coroutine_self(void);
*/
bool qemu_in_coroutine(void);
-
+void coroutine_pool_cleanup(void);
/**
* CoQueues are a mechanism to queue coroutines in order to continue executing
diff --git a/iothread.c b/iothread.c
index 342a23f..b53529b 100644
--- a/iothread.c
+++ b/iothread.c
@@ -15,6 +15,7 @@
#include "qom/object_interfaces.h"
#include "qemu/module.h"
#include "block/aio.h"
+#include "block/coroutine.h"
#include "sysemu/iothread.h"
#include "qmp-commands.h"
#include "qemu/error-report.h"
@@ -47,6 +48,8 @@ static void *iothread_run(void *opaque)
}
aio_context_release(iothread->ctx);
}
+
+ coroutine_pool_cleanup();
return NULL;
}
diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index 4708521..1900155 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -24,22 +24,22 @@ 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;
+static __thread struct CoRoutinePool {
+ Coroutine *ptrs[POOL_MAX_SIZE];
+ unsigned int size;
+ unsigned int nextfree;
+} CoPool;
Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
{
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--;
+ if (CoPool.size) {
+ co = CoPool.ptrs[CoPool.nextfree];
+ CoPool.size--;
+ CoPool.nextfree--;
+ CoPool.nextfree &= (POOL_MAX_SIZE - 1);
}
- qemu_mutex_unlock(&pool_lock);
}
if (!co) {
@@ -54,36 +54,30 @@ Coroutine *qemu_coroutine_create(CoroutineEntry *entry)
static void coroutine_delete(Coroutine *co)
{
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;
+ CoPool.nextfree++;
+ CoPool.nextfree &= (POOL_MAX_SIZE - 1);
+ if (CoPool.size == POOL_MAX_SIZE) {
+ qemu_coroutine_delete(CoPool.ptrs[CoPool.nextfree]);
+ } else {
+ CoPool.size++;
}
- qemu_mutex_unlock(&pool_lock);
+ co->caller = NULL;
+ CoPool.ptrs[CoPool.nextfree] = co;
+ } else {
+ qemu_coroutine_delete(co);
}
-
- qemu_coroutine_delete(co);
}
static void __attribute__((constructor)) coroutine_pool_init(void)
{
- qemu_mutex_init(&pool_lock);
}
-static void __attribute__((destructor)) coroutine_pool_cleanup(void)
+void __attribute__((destructor)) coroutine_pool_cleanup(void)
{
- Coroutine *co;
- Coroutine *tmp;
-
- QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
- QSLIST_REMOVE_HEAD(&pool, pool_next);
- qemu_coroutine_delete(co);
+ printf("coroutine_pool_cleanup %lx pool %p\n", pthread_self(), &CoPool);
+ while (CoPool.size) {
+ qemu_coroutine_delete(qemu_coroutine_create(NULL));
}
-
- qemu_mutex_destroy(&pool_lock);
}
static void coroutine_swap(Coroutine *from, Coroutine *to)
--
1.7.9.5
- [Qemu-devel] [RFC PATCH 0/3] qemu-coroutine: use a ring per thread for the pool, Peter Lieven, 2014/11/27
- [Qemu-devel] [RFC PATCH 2/3] block/block-backend.c: remove coroutine pool reservation, Peter Lieven, 2014/11/27
- [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool,
Peter Lieven <=
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Paolo Bonzini, 2014/11/27
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Peter Lieven, 2014/11/28
- Message not available
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Peter Lieven, 2014/11/28
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Paolo Bonzini, 2014/11/28
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Peter Lieven, 2014/11/28
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Paolo Bonzini, 2014/11/28
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Peter Lieven, 2014/11/28
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Peter Lieven, 2014/11/28
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Peter Lieven, 2014/11/28
- Re: [Qemu-devel] [RFC PATCH 3/3] qemu-coroutine: use a ring per thread for the pool, Paolo Bonzini, 2014/11/28