Blame 0022-coroutine-switch-per-thread-free-pool-to-a-global-po.patch

Justin M. Forbes 45e84a
From fe5c13ebf1161d0f324229cfb36cb5fb87ec6248 Mon Sep 17 00:00:00 2001
Justin M. Forbes 45e84a
From: Avi Kivity <avi@redhat.com>
Justin M. Forbes 45e84a
Date: Mon, 5 Dec 2011 19:20:12 +0200
Justin M. Forbes 45e84a
Subject: [PATCH 22/25] coroutine: switch per-thread free pool to a global
Justin M. Forbes 45e84a
 pool
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
ucontext-based coroutines use a free pool to reduce allocations and
Justin M. Forbes 45e84a
deallocations of coroutine objects.  The pool is per-thread, presumably
Justin M. Forbes 45e84a
to improve locality.  However, as coroutines are usually allocated in
Justin M. Forbes 45e84a
a vcpu thread and freed in the I/O thread, the pool accounting gets
Justin M. Forbes 45e84a
screwed up and we end allocating and freeing a coroutine for every I/O
Justin M. Forbes 45e84a
request.  This is expensive since large objects are allocated via the
Justin M. Forbes 45e84a
kernel, and are not cached by the C runtime.
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Fix by switching to a global pool.  This is safe since we're protected
Justin M. Forbes 45e84a
by the global mutex.
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
Signed-off-by: Avi Kivity <avi@redhat.com>
Justin M. Forbes 45e84a
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Justin M. Forbes 45e84a
---
Justin M. Forbes 45e84a
 coroutine-ucontext.c |   30 ++++++++++++++++--------------
Justin M. Forbes 45e84a
 1 files changed, 16 insertions(+), 14 deletions(-)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
Justin M. Forbes 45e84a
index 2b8d3e9..3d01075 100644
Justin M. Forbes 45e84a
--- a/coroutine-ucontext.c
Justin M. Forbes 45e84a
+++ b/coroutine-ucontext.c
Justin M. Forbes 45e84a
@@ -35,6 +35,10 @@ enum {
Justin M. Forbes 45e84a
     POOL_MAX_SIZE = 64,
Justin M. Forbes 45e84a
 };
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
+/** Free list to speed up creation */
Justin M. Forbes 45e84a
+static QLIST_HEAD(, Coroutine) pool = QLIST_HEAD_INITIALIZER(pool);
Justin M. Forbes 45e84a
+static unsigned int pool_size;
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
 typedef struct {
Justin M. Forbes 45e84a
     Coroutine base;
Justin M. Forbes 45e84a
     void *stack;
Justin M. Forbes 45e84a
@@ -48,10 +52,6 @@ typedef struct {
Justin M. Forbes 45e84a
     /** Currently executing coroutine */
Justin M. Forbes 45e84a
     Coroutine *current;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-    /** Free list to speed up creation */
Justin M. Forbes 45e84a
-    QLIST_HEAD(, Coroutine) pool;
Justin M. Forbes 45e84a
-    unsigned int pool_size;
Justin M. Forbes 45e84a
-
Justin M. Forbes 45e84a
     /** The default coroutine */
Justin M. Forbes 45e84a
     CoroutineUContext leader;
Justin M. Forbes 45e84a
 } CoroutineThreadState;
Justin M. Forbes 45e84a
@@ -75,7 +75,6 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
Justin M. Forbes 45e84a
     if (!s) {
Justin M. Forbes 45e84a
         s = g_malloc0(sizeof(*s));
Justin M. Forbes 45e84a
         s->current = &s->leader.base;
Justin M. Forbes 45e84a
-        QLIST_INIT(&s->pool);
Justin M. Forbes 45e84a
         pthread_setspecific(thread_state_key, s);
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
     return s;
Justin M. Forbes 45e84a
@@ -84,14 +83,19 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
Justin M. Forbes 45e84a
 static void qemu_coroutine_thread_cleanup(void *opaque)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
     CoroutineThreadState *s = opaque;
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+    g_free(s);
Justin M. Forbes 45e84a
+}
Justin M. Forbes 45e84a
+
Justin M. Forbes 45e84a
+static void __attribute__((destructor)) coroutine_cleanup(void)
Justin M. Forbes 45e84a
+{
Justin M. Forbes 45e84a
     Coroutine *co;
Justin M. Forbes 45e84a
     Coroutine *tmp;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-    QLIST_FOREACH_SAFE(co, &s->pool, pool_next, tmp) {
Justin M. Forbes 45e84a
+    QLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
Justin M. Forbes 45e84a
         g_free(DO_UPCAST(CoroutineUContext, base, co)->stack);
Justin M. Forbes 45e84a
         g_free(co);
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
-    g_free(s);
Justin M. Forbes 45e84a
 }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
 static void __attribute__((constructor)) coroutine_init(void)
Justin M. Forbes 45e84a
@@ -169,13 +173,12 @@ static Coroutine *coroutine_new(void)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
 Coroutine *qemu_coroutine_new(void)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
-    CoroutineThreadState *s = coroutine_get_thread_state();
Justin M. Forbes 45e84a
     Coroutine *co;
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-    co = QLIST_FIRST(&s->pool);
Justin M. Forbes 45e84a
+    co = QLIST_FIRST(&pool);
Justin M. Forbes 45e84a
     if (co) {
Justin M. Forbes 45e84a
         QLIST_REMOVE(co, pool_next);
Justin M. Forbes 45e84a
-        s->pool_size--;
Justin M. Forbes 45e84a
+        pool_size--;
Justin M. Forbes 45e84a
     } else {
Justin M. Forbes 45e84a
         co = coroutine_new();
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
@@ -184,13 +187,12 @@ Coroutine *qemu_coroutine_new(void)
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
 void qemu_coroutine_delete(Coroutine *co_)
Justin M. Forbes 45e84a
 {
Justin M. Forbes 45e84a
-    CoroutineThreadState *s = coroutine_get_thread_state();
Justin M. Forbes 45e84a
     CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-    if (s->pool_size < POOL_MAX_SIZE) {
Justin M. Forbes 45e84a
-        QLIST_INSERT_HEAD(&s->pool, &co->base, pool_next);
Justin M. Forbes 45e84a
+    if (pool_size < POOL_MAX_SIZE) {
Justin M. Forbes 45e84a
+        QLIST_INSERT_HEAD(&pool, &co->base, pool_next);
Justin M. Forbes 45e84a
         co->base.caller = NULL;
Justin M. Forbes 45e84a
-        s->pool_size++;
Justin M. Forbes 45e84a
+        pool_size++;
Justin M. Forbes 45e84a
         return;
Justin M. Forbes 45e84a
     }
Justin M. Forbes 45e84a
Justin M. Forbes 45e84a
-- 
Justin M. Forbes 45e84a
1.7.7.5
Justin M. Forbes 45e84a