[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH] coroutine: always use pooling
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PATCH] coroutine: always use pooling |
Date: |
Tue, 25 Sep 2012 14:44:06 +0200 |
It makes sense to use it for other implementations than ucontext, too.
Signed-off-by: Paolo Bonzini <address@hidden>
---
coroutine-ucontext.c | 43 +------------------------------------------
qemu-coroutine.c | 38 ++++++++++++++++++++++++++++++++++++--
2 file modificati, 37 inserzioni(+), 44 rimozioni(-)
diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
index 784081a..744f4f6 100644
--- a/coroutine-ucontext.c
+++ b/coroutine-ucontext.c
@@ -34,15 +34,6 @@
#include <valgrind/valgrind.h>
#endif
-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;
-
typedef struct {
Coroutine base;
void *stack;
@@ -96,17 +87,6 @@ static void qemu_coroutine_thread_cleanup(void *opaque)
g_free(s);
}
-static void __attribute__((destructor)) coroutine_cleanup(void)
-{
- Coroutine *co;
- Coroutine *tmp;
-
- QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
- g_free(DO_UPCAST(CoroutineUContext, base, co)->stack);
- g_free(co);
- }
-}
-
static void __attribute__((constructor)) coroutine_init(void)
{
int ret;
@@ -140,7 +120,7 @@ static void coroutine_trampoline(int i0, int i1)
}
}
-static Coroutine *coroutine_new(void)
+Coroutine *qemu_coroutine_new(void)
{
const size_t stack_size = 1 << 20;
CoroutineUContext *co;
@@ -185,20 +165,6 @@ static Coroutine *coroutine_new(void)
return &co->base;
}
-Coroutine *qemu_coroutine_new(void)
-{
- Coroutine *co;
-
- co = QSLIST_FIRST(&pool);
- if (co) {
- QSLIST_REMOVE_HEAD(&pool, pool_next);
- pool_size--;
- } else {
- co = coroutine_new();
- }
- return co;
-}
-
#ifdef CONFIG_VALGRIND_H
#ifdef CONFIG_PRAGMA_DISABLE_UNUSED_BUT_SET
/* Work around an unused variable in the valgrind.h macro... */
@@ -217,13 +183,6 @@ void qemu_coroutine_delete(Coroutine *co_)
{
CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
- if (pool_size < POOL_MAX_SIZE) {
- QSLIST_INSERT_HEAD(&pool, &co->base, pool_next);
- co->base.caller = NULL;
- pool_size++;
- return;
- }
-
#ifdef CONFIG_VALGRIND_H
valgrind_stack_deregister(co);
#endif
diff --git a/qemu-coroutine.c b/qemu-coroutine.c
index 600be26..5a86837 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -17,9 +17,26 @@
#include "qemu-coroutine.h"
#include "qemu-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;
}
@@ -35,13 +52,30 @@ static void coroutine_swap(Coroutine *from, Coroutine *to)
return;
case COROUTINE_TERMINATE:
trace_qemu_coroutine_terminate(to);
- qemu_coroutine_delete(to);
+
+ if (pool_size < POOL_MAX_SIZE) {
+ QSLIST_INSERT_HEAD(&pool, to, pool_next);
+ to->caller = NULL;
+ pool_size++;
+ } else {
+ qemu_coroutine_delete(to);
+ }
return;
default:
abort();
}
}
+static void __attribute__((destructor)) coroutine_cleanup(void)
+{
+ Coroutine *co;
+ Coroutine *tmp;
+
+ QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
+ qemu_coroutine_delete(co);
+ }
+}
+
void qemu_coroutine_enter(Coroutine *co, void *opaque)
{
Coroutine *self = qemu_coroutine_self();
--
1.7.12
- [Qemu-devel] [PATCH] coroutine: always use pooling,
Paolo Bonzini <=