X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/e06516f565dca3636a4cbef770b191a5fcdf63ab..200bf596b96820186883953de9bda26cac8e6bd7:/coroutine-ucontext.c diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c index 41c2379a2a..5f43083af5 100644 --- a/coroutine-ucontext.c +++ b/coroutine-ucontext.c @@ -35,6 +35,10 @@ enum { 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; @@ -48,10 +52,6 @@ typedef struct { /** Currently executing coroutine */ Coroutine *current; - /** Free list to speed up creation */ - QLIST_HEAD(, Coroutine) pool; - unsigned int pool_size; - /** The default coroutine */ CoroutineUContext leader; } CoroutineThreadState; @@ -73,9 +73,8 @@ static CoroutineThreadState *coroutine_get_thread_state(void) CoroutineThreadState *s = pthread_getspecific(thread_state_key); if (!s) { - s = qemu_mallocz(sizeof(*s)); + s = g_malloc0(sizeof(*s)); s->current = &s->leader.base; - QLIST_INIT(&s->pool); pthread_setspecific(thread_state_key, s); } return s; @@ -84,14 +83,19 @@ static CoroutineThreadState *coroutine_get_thread_state(void) static void qemu_coroutine_thread_cleanup(void *opaque) { CoroutineThreadState *s = opaque; + + g_free(s); +} + +static void __attribute__((destructor)) coroutine_cleanup(void) +{ Coroutine *co; Coroutine *tmp; - QLIST_FOREACH_SAFE(co, &s->pool, pool_next, tmp) { - qemu_free(DO_UPCAST(CoroutineUContext, base, co)->stack); - qemu_free(co); + QSLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) { + g_free(DO_UPCAST(CoroutineUContext, base, co)->stack); + g_free(co); } - qemu_free(s); } static void __attribute__((constructor)) coroutine_init(void) @@ -133,7 +137,7 @@ static Coroutine *coroutine_new(void) CoroutineUContext *co; ucontext_t old_uc, uc; jmp_buf old_env; - union cc_arg arg; + union cc_arg arg = {0}; /* The ucontext functions preserve signal masks which incurs a system call * overhead. setjmp()/longjmp() does not preserve signal masks but only @@ -146,8 +150,8 @@ static Coroutine *coroutine_new(void) abort(); } - co = qemu_mallocz(sizeof(*co)); - co->stack = qemu_malloc(stack_size); + co = g_malloc0(sizeof(*co)); + co->stack = g_malloc(stack_size); co->base.entry_arg = &old_env; /* stash away our jmp_buf */ uc.uc_link = &old_uc; @@ -169,13 +173,12 @@ static Coroutine *coroutine_new(void) Coroutine *qemu_coroutine_new(void) { - CoroutineThreadState *s = coroutine_get_thread_state(); Coroutine *co; - co = QLIST_FIRST(&s->pool); + co = QSLIST_FIRST(&pool); if (co) { - QLIST_REMOVE(co, pool_next); - s->pool_size--; + QSLIST_REMOVE_HEAD(&pool, pool_next); + pool_size--; } else { co = coroutine_new(); } @@ -184,18 +187,17 @@ Coroutine *qemu_coroutine_new(void) void qemu_coroutine_delete(Coroutine *co_) { - CoroutineThreadState *s = coroutine_get_thread_state(); CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_); - if (s->pool_size < POOL_MAX_SIZE) { - QLIST_INSERT_HEAD(&s->pool, &co->base, pool_next); + if (pool_size < POOL_MAX_SIZE) { + QSLIST_INSERT_HEAD(&pool, &co->base, pool_next); co->base.caller = NULL; - s->pool_size++; + pool_size++; return; } - qemu_free(co->stack); - qemu_free(co); + g_free(co->stack); + g_free(co); } CoroutineAction qemu_coroutine_switch(Coroutine *from_, Coroutine *to_,