qemu-devel
[Top][All Lists]
Advanced

[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




reply via email to

[Prev in Thread] Current Thread [Next in Thread]