Patchwork [15/22] coroutine: move pooling to common code

login
register
mail settings
Submitter Kevin Wolf
Date Feb. 22, 2013, 9:23 p.m.
Message ID <1361568231-18198-16-git-send-email-kwolf@redhat.com>
Download mbox | patch
Permalink /patch/222659/
State New
Headers show

Comments

Kevin Wolf - Feb. 22, 2013, 9:23 p.m.
From: Paolo Bonzini <pbonzini@redhat.com>

The coroutine pool code is duplicated between the ucontext and
sigaltstack backends, and absent from the win32 backend.  But the
code can be shared easily by moving it to qemu-coroutine.c.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 coroutine-sigaltstack.c | 43 +------------------------------------------
 coroutine-ucontext.c    | 43 +------------------------------------------
 qemu-coroutine.c        | 45 +++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 45 insertions(+), 86 deletions(-)

Patch

diff --git a/coroutine-sigaltstack.c b/coroutine-sigaltstack.c
index e37ebac..b4d1762 100644
--- a/coroutine-sigaltstack.c
+++ b/coroutine-sigaltstack.c
@@ -33,15 +33,6 @@ 
 #include "qemu-common.h"
 #include "block/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;
-
 typedef struct {
     Coroutine base;
     void *stack;
@@ -85,17 +76,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;
@@ -164,7 +144,7 @@  static void coroutine_trampoline(int signal)
     coroutine_bootstrap(self, co);
 }
 
-static Coroutine *coroutine_new(void)
+Coroutine *qemu_coroutine_new(void)
 {
     const size_t stack_size = 1 << 20;
     CoroutineUContext *co;
@@ -272,31 +252,10 @@  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;
-}
-
 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;
-    }
-
     g_free(co->stack);
     g_free(co);
 }
diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
index a9c30e9..6f8ffa8 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_DIAGNOSTIC_AVAILABLE
 /* 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 0f6e268..25a14c6 100644
--- a/qemu-coroutine.c
+++ b/qemu-coroutine.c
@@ -17,13 +17,54 @@ 
 #include "block/coroutine.h"
 #include "block/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;
 }
 
+static void coroutine_delete(Coroutine *co)
+{
+    if (pool_size < POOL_MAX_SIZE) {
+        QSLIST_INSERT_HEAD(&pool, co, pool_next);
+        co->caller = NULL;
+        pool_size++;
+        return;
+    }
+
+    qemu_coroutine_delete(co);
+}
+
+static void __attribute__((destructor)) coroutine_cleanup(void)
+{
+    Coroutine *co;
+    Coroutine *tmp;
+
+    QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
+        QSLIST_REMOVE_HEAD(&pool, pool_next);
+        qemu_coroutine_delete(co);
+    }
+}
+
 static void coroutine_swap(Coroutine *from, Coroutine *to)
 {
     CoroutineAction ret;
@@ -35,7 +76,7 @@  static void coroutine_swap(Coroutine *from, Coroutine *to)
         return;
     case COROUTINE_TERMINATE:
         trace_qemu_coroutine_terminate(to);
-        qemu_coroutine_delete(to);
+        coroutine_delete(to);
         return;
     default:
         abort();