From 30a78d30b3467f141c2120f6f6549c6d64a146dd Mon Sep 17 00:00:00 2001 From: Xie Han <63350856@qq.com> Date: Sun, 26 May 2024 03:18:32 +0800 Subject: [PATCH] Add thrdpool_decrease(). --- src/kernel/thrdpool.c | 51 ++++++++++++++++++++++++++++++++----------- src/kernel/thrdpool.h | 1 + 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/src/kernel/thrdpool.c b/src/kernel/thrdpool.c index ce41dd08..5e6982cb 100644 --- a/src/kernel/thrdpool.c +++ b/src/kernel/thrdpool.c @@ -41,13 +41,31 @@ struct __thrdpool_task_entry static pthread_t __zero_tid; +static void __thrdpool_exit_routine(void *context) +{ + thrdpool_t *pool = (thrdpool_t *)context; + pthread_t tid; + + /* One thread joins another. Don't need to keep all thread IDs. */ + pthread_mutex_lock(&pool->mutex); + tid = pool->tid; + pool->tid = pthread_self(); + if (--pool->nthreads == 0 && pool->terminate) + pthread_cond_signal(pool->terminate); + + pthread_mutex_unlock(&pool->mutex); + if (!pthread_equal(tid, __zero_tid)) + pthread_join(tid, NULL); + + pthread_exit(NULL); +} + static void *__thrdpool_routine(void *arg) { thrdpool_t *pool = (thrdpool_t *)arg; struct __thrdpool_task_entry *entry; void (*task_routine)(void *); void *task_context; - pthread_t tid; pthread_setspecific(pool->key, pool); while (!pool->terminate) @@ -69,17 +87,7 @@ static void *__thrdpool_routine(void *arg) } } - /* One thread joins another. Don't need to keep all thread IDs. */ - pthread_mutex_lock(&pool->mutex); - tid = pool->tid; - pool->tid = pthread_self(); - if (--pool->nthreads == 0) - pthread_cond_signal(pool->terminate); - - pthread_mutex_unlock(&pool->mutex); - if (!pthread_equal(tid, __zero_tid)) - pthread_join(tid, NULL); - + __thrdpool_exit_routine(pool); return NULL; } @@ -227,6 +235,23 @@ int thrdpool_increase(thrdpool_t *pool) return -1; } +int thrdpool_decrease(thrdpool_t *pool) +{ + void *buf = malloc(sizeof (struct __thrdpool_task_entry)); + struct __thrdpool_task_entry *entry; + + if (buf) + { + entry = (struct __thrdpool_task_entry *)buf; + entry->task.routine = __thrdpool_exit_routine; + entry->task.context = pool; + msgqueue_put_head(entry, pool->msgqueue); + return 0; + } + + return -1; +} + inline int thrdpool_in_pool(thrdpool_t *pool); int thrdpool_in_pool(thrdpool_t *pool) @@ -247,7 +272,7 @@ void thrdpool_destroy(void (*pending)(const struct thrdpool_task *), if (!entry) break; - if (pending) + if (pending && entry->task.routine != __thrdpool_exit_routine) pending(&entry->task); free(entry); diff --git a/src/kernel/thrdpool.h b/src/kernel/thrdpool.h index 71f4b2dc..5575216a 100644 --- a/src/kernel/thrdpool.h +++ b/src/kernel/thrdpool.h @@ -49,6 +49,7 @@ extern "C" thrdpool_t *thrdpool_create(size_t nthreads, size_t stacksize); int thrdpool_schedule(const struct thrdpool_task *task, thrdpool_t *pool); int thrdpool_increase(thrdpool_t *pool); +int thrdpool_decrease(thrdpool_t *pool); int thrdpool_in_pool(thrdpool_t *pool); void thrdpool_destroy(void (*pending)(const struct thrdpool_task *), thrdpool_t *pool);