gwion-util
utilities for the Gwion project
Loading...
Searching...
No Matches
threadpool.c
Go to the documentation of this file.
1#include "gwion_util.h"
2
3typedef struct {
4 void (*routine)(void *);
5 void *arg;
6} task_t;
7
22
23ANN static gwtreturn_t threadpool_thread(void *data) {
24 threadpool_t *p = (threadpool_t *)data;
25 while(true) {
26 (void)gwt_lock(&p->lock);
27 while(!p->active && !p->shutdown)
28 (void)gwt_wait(&p->cond, &p->lock);
29 if(p->shutdown) break;
30 task_t task = p->queue[p->head];
31 p->head = (p->head + 1) % p->queue_size;
32 p->active--;
33 (void)gwt_unlock(&p->lock);
34 task.routine(task.arg);
35 }
36 (void)gwt_unlock(&p->lock);
37 THREAD_RETURN(NULL);
38}
39
40ANN static bool alloc(threadpool_t *p, const uint32_t thread_count,
41 const uint32_t queue_size) {
42 return !(p->threads = malloc(thread_count * sizeof(gwtthread_t))) ||
43 !(p->queue = malloc(queue_size * sizeof(task_t)));
44}
45
46ANN static bool utils(threadpool_t *p) {
47#ifdef BUILD_ON_WINDOWS
48 p->lock = NULL;
49#endif
50 if(gwt_lock_ini(&p->lock)) return false;
51 p->has_lock = true;
52 if(gwt_cond_ini(&p->cond)) return false;
53 p->has_cond = true;
54 return true;
55}
56
57ANN static bool start(threadpool_t *p, const uint32_t thread_count) {
58 for(uint32_t i = 0; i < thread_count; i++) {
59 const int ret = gwt_create(&p->threads[i], threadpool_thread, p);
60 if(ret) return false;
61 p->started++;
62 }
63 return true;
64}
65
66ANN2(1, 2) static bool add(threadpool_t *pool, void (*routine)(void *), void *arg) {
67 if(unlikely(pool->shutdown || pool->active == pool->queue_size))
68 return false;
69 const uint32_t next = (pool->tail + 1) % pool->queue_size;
70 task_t t = { .routine = routine, .arg = arg };
71 pool->queue[pool->tail] = t;
72 pool->tail = next;
73 pool->active++;
74 (void)gwt_signal(&pool->cond);
75 return true;
76}
77
78bool threadpool_add(threadpool_t *p, void (*routine)(void *), void *arg) {
79 (void)gwt_lock(&p->lock);
80 const bool ret = add(p, routine, arg);
81 (void)gwt_unlock(&p->lock);
82 return ret;
83}
84
86 (void)gwt_lock(&p->lock);
87 p->shutdown = true;
89 (void)gwt_unlock(&p->lock);
90 if(p->threads) {
91 for(uint32_t i = 0; i < p->started; i++)
92 gwt_join(p->threads[i]);
93 free(p->threads);
94 }
95 if(p->queue) free(p->queue);
96 if(p->has_lock) gwt_lock_end(&p->lock);
97 if(p->has_cond) gwt_cond_end(&p->cond);
98 free(p);
99}
100
101threadpool_t *new_threadpool(const uint32_t thread_count, const uint32_t queue_size) {
102 threadpool_t *p = malloc(sizeof(threadpool_t));
103 if(!p) return NULL;
104 p->head = p->tail = p->active = 0;
105 p->shutdown = p->has_lock = p->has_cond = false;
106 p->started = 0;
107 p->queue_size = queue_size;
108 if(alloc(p, thread_count, queue_size) || !utils(p) ||
109 !start(p, thread_count)) {
111 return NULL;
112 }
113 return p;
114}
115
116
#define ANN
Definition defs.h:18
#define ANN2(...)
Definition defs.h:19
#define unlikely(x)
Definition defs.h:38
#define THREAD_RETURN(arg)
meta header (use this to include the whole library)
Definition mpool.c:15
void(* routine)(void *)
Definition threadpool.c:4
void * arg
Definition threadpool.c:5
gwtthread_t * threads
Definition threadpool.c:11
uint32_t started
Definition threadpool.c:17
gwtlock_t lock
Definition threadpool.c:9
uint32_t queue_size
Definition threadpool.c:16
uint32_t tail
Definition threadpool.c:14
task_t * queue
Definition threadpool.c:12
uint32_t head
Definition threadpool.c:13
uint32_t active
Definition threadpool.c:15
gwtcond_t cond
Definition threadpool.c:10
bool threadpool_add(threadpool_t *p, void(*routine)(void *), void *arg)
Definition threadpool.c:78
static ANN bool start(threadpool_t *p, const uint32_t thread_count)
Definition threadpool.c:57
static ANN gwtreturn_t threadpool_thread(void *data)
Definition threadpool.c:23
static ANN bool utils(threadpool_t *p)
Definition threadpool.c:46
static ANN bool alloc(threadpool_t *p, const uint32_t thread_count, const uint32_t queue_size)
Definition threadpool.c:40
ANN void free_threadpool(threadpool_t *p)
Definition threadpool.c:85
threadpool_t * new_threadpool(const uint32_t thread_count, const uint32_t queue_size)
Definition threadpool.c:101
pthread_cond_t gwtcond_t
Definition threadpool.h:12
static ANN bool gwt_create(gwtthread_t *thread, gwtreturn_t(*fun)(void *), void *arg)
Definition threadpool.h:103
static ANN void gwt_cond_end(gwtcond_t *cond)
Definition threadpool.h:100
static ANN int gwt_cond_ini(gwtcond_t *cond)
Definition threadpool.h:97
void(* routine)(void *)
Definition threadpool.h:26
pthread_mutex_t gwtlock_t
Definition threadpool.h:11
void * gwtreturn_t
Definition threadpool.h:13
static ANN int gwt_broadcast(gwtcond_t *cond)
Definition threadpool.h:82
static ANN int gwt_unlock(gwtlock_t *lock)
Definition threadpool.h:73
static ANN void gwt_join(gwtthread_t thread)
Definition threadpool.h:76
static ANN void gwt_lock_end(gwtlock_t *lock)
Definition threadpool.h:94
static ANN int gwt_lock_ini(gwtlock_t *lock)
Definition threadpool.h:88
static ANN int gwt_signal(gwtcond_t *cond)
Definition threadpool.h:85
static ANN void gwt_wait(gwtcond_t *cond, gwtlock_t *lock)
Definition threadpool.h:79
static ANN int gwt_lock(gwtlock_t *lock)
Definition threadpool.h:70
void void * arg
Definition threadpool.h:26
pthread_t gwtthread_t
Definition threadpool.h:10