From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:39280) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X48mF-0004Xu-VA for qemu-devel@nongnu.org; Mon, 07 Jul 2014 09:16:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X48m7-0006GM-WB for qemu-devel@nongnu.org; Mon, 07 Jul 2014 09:16:15 -0400 Received: from mx1.redhat.com ([209.132.183.28]:62075) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X48m7-0006G8-Mr for qemu-devel@nongnu.org; Mon, 07 Jul 2014 09:16:07 -0400 From: Stefan Hajnoczi Date: Mon, 7 Jul 2014 15:15:52 +0200 Message-Id: <1404738953-13221-2-git-send-email-stefanha@redhat.com> In-Reply-To: <1404738953-13221-1-git-send-email-stefanha@redhat.com> References: <1404738953-13221-1-git-send-email-stefanha@redhat.com> Subject: [Qemu-devel] [PATCH v3 1/2] coroutine: make pool size dynamic List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Kevin Wolf , ming.lei@canonical.com, Markus Armbruster , Stefan Hajnoczi , Paolo Bonzini , =?UTF-8?q?Llu=C3=ADs=20Vilanova?= Allow coroutine users to adjust the pool size. For example, if the guest has multiple emulated disk drives we should keep around more coroutines. Signed-off-by: Stefan Hajnoczi --- include/block/coroutine.h | 11 +++++++++++ qemu-coroutine.c | 26 +++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 3 deletions(-) diff --git a/include/block/coroutine.h b/include/block/coroutine.h index a1797ae..07eeb3c 100644 --- a/include/block/coroutine.h +++ b/include/block/coroutine.h @@ -223,4 +223,15 @@ void coroutine_fn co_aio_sleep_ns(AioContext *ctx, QEMUClockType type, * Note that this function clobbers the handlers for the file descriptor. */ void coroutine_fn yield_until_fd_readable(int fd); + +/** + * Add or subtract from the coroutine pool size + * + * The coroutine implementation keeps a pool of coroutines to be reused by + * qemu_coroutine_create(). This makes coroutine creation cheap. Heavy + * coroutine users should call this to reserve pool space. Call it again with + * a negative number to release pool space. + */ +void qemu_coroutine_adjust_pool_size(int n); + #endif /* QEMU_COROUTINE_H */ diff --git a/qemu-coroutine.c b/qemu-coroutine.c index 4708521..bd574aa 100644 --- a/qemu-coroutine.c +++ b/qemu-coroutine.c @@ -19,14 +19,14 @@ #include "block/coroutine_int.h" enum { - /* Maximum free pool size prevents holding too many freed coroutines */ - POOL_MAX_SIZE = 64, + POOL_DEFAULT_SIZE = 64, }; /** Free list to speed up creation */ static QemuMutex pool_lock; static QSLIST_HEAD(, Coroutine) pool = QSLIST_HEAD_INITIALIZER(pool); static unsigned int pool_size; +static unsigned int pool_max_size = POOL_DEFAULT_SIZE; Coroutine *qemu_coroutine_create(CoroutineEntry *entry) { @@ -55,7 +55,7 @@ static void coroutine_delete(Coroutine *co) { if (CONFIG_COROUTINE_POOL) { qemu_mutex_lock(&pool_lock); - if (pool_size < POOL_MAX_SIZE) { + if (pool_size < pool_max_size) { QSLIST_INSERT_HEAD(&pool, co, pool_next); co->caller = NULL; pool_size++; @@ -137,3 +137,23 @@ void coroutine_fn qemu_coroutine_yield(void) self->caller = NULL; coroutine_swap(self, to); } + +void qemu_coroutine_adjust_pool_size(int n) +{ + qemu_mutex_lock(&pool_lock); + + pool_max_size += n; + + /* Callers should never take away more than they added */ + assert(pool_max_size >= POOL_DEFAULT_SIZE); + + /* Trim oversized pool down to new max */ + while (pool_size > pool_max_size) { + Coroutine *co = QSLIST_FIRST(&pool); + QSLIST_REMOVE_HEAD(&pool, pool_next); + pool_size--; + qemu_coroutine_delete(co); + } + + qemu_mutex_unlock(&pool_lock); +} -- 1.9.3