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 (*fun)(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.fun(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
66threadpool_t *new_threadpool(const uint32_t thread_count, const uint32_t queue_size) {
67 threadpool_t *p = malloc(sizeof(threadpool_t));
68 if(!p) return NULL;
69 p->head = p->tail = p->active = 0;
70 p->shutdown = p->has_lock = p->has_cond = false;
71 p->started = 0;
72 p->queue_size = queue_size;
73 if(alloc(p, thread_count, queue_size) || !utils(p) ||
74 !start(p, thread_count)) {
76 return NULL;
77 }
78 return p;
79}
80
81ANN2(1, 2) static bool add(threadpool_t *p, void (*fun)(void *), void *arg) {
82 if(unlikely(p->shutdown || p->active == p->queue_size))
83 return false;
84 const uint32_t next = (p->tail + 1) % p->queue_size;
85 task_t t = { .fun = fun, .arg = arg };
86 p->queue[p->tail] = t;
87 p->tail = next;
88 p->active++;
89 (void)gwt_signal(&p->cond);
90 return true;
91}
92
93bool threadpool_add(threadpool_t *p, void (*fun)(void *), void *arg) {
94 (void)gwt_lock(&p->lock);
95 const bool ret = add(p, fun, arg);
96 (void)gwt_unlock(&p->lock);
97 return ret;
98}
99
101 (void)gwt_lock(&p->lock);
102 p->shutdown = true;
103 gwt_broadcast(&p->cond);
104 (void)gwt_unlock(&p->lock);
105 if(p->threads) {
106 for(uint32_t i = 0; i < p->started; i++)
107 gwt_join(p->threads[i]);
108 free(p->threads);
109 }
110 if(p->queue) free(p->queue);
111 if(p->has_lock) gwt_lock_end(&p->lock);
112 if(p->has_cond) gwt_cond_end(&p->cond);
113}
#define ANN
Definition defs.h:19
#define ANN2(...)
Definition defs.h:20
#define unlikely(x)
Definition defs.h:39
#define THREAD_RETURN(arg)
meta header (use this to include the whole library)
void(* fun)(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(*fun)(void *), void *arg)
Definition threadpool.c:93
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:100
threadpool_t * new_threadpool(const uint32_t thread_count, const uint32_t queue_size)
Definition threadpool.c:66
pthread_cond_t gwtcond_t
Definition threadpool.h:13
static ANN bool gwt_create(gwtthread_t *thread, gwtreturn_t(*fun)(void *), void *arg)
Definition threadpool.h:104
static ANN void gwt_cond_end(gwtcond_t *cond)
Definition threadpool.h:101
static ANN int gwt_cond_ini(gwtcond_t *cond)
Definition threadpool.h:98
pthread_mutex_t gwtlock_t
Definition threadpool.h:12
void * gwtreturn_t
Definition threadpool.h:14
static ANN int gwt_broadcast(gwtcond_t *cond)
Definition threadpool.h:83
static ANN int gwt_unlock(gwtlock_t *lock)
Definition threadpool.h:74
static ANN void gwt_join(gwtthread_t thread)
Definition threadpool.h:77
static ANN void gwt_lock_end(gwtlock_t *lock)
Definition threadpool.h:95
static ANN int gwt_lock_ini(gwtlock_t *lock)
Definition threadpool.h:89
static ANN int gwt_signal(gwtcond_t *cond)
Definition threadpool.h:86
static ANN void gwt_wait(gwtcond_t *cond, gwtlock_t *lock)
Definition threadpool.h:80
static ANN int gwt_lock(gwtlock_t *lock)
Definition threadpool.h:71
void void * arg
Definition threadpool.h:27
pthread_t gwtthread_t
Definition threadpool.h:11