From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:55105) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TGUV1-0000C4-Lb for qemu-devel@nongnu.org; Tue, 25 Sep 2012 08:44:33 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TGUUx-0004Mk-Jy for qemu-devel@nongnu.org; Tue, 25 Sep 2012 08:44:27 -0400 Received: from mail-pb0-f45.google.com ([209.85.160.45]:33436) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TGUUx-0004Ma-EU for qemu-devel@nongnu.org; Tue, 25 Sep 2012 08:44:23 -0400 Received: by pbbrp2 with SMTP id rp2so51138pbb.4 for ; Tue, 25 Sep 2012 05:44:22 -0700 (PDT) Sender: Paolo Bonzini From: Paolo Bonzini Date: Tue, 25 Sep 2012 14:44:06 +0200 Message-Id: <1348577046-12643-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH] coroutine: always use pooling List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: kwolf@redhat.com, stefanha@gmail.com It makes sense to use it for other implementations than ucontext, too. Signed-off-by: Paolo Bonzini --- 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 #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