summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ll.c12
-rw-r--r--src/ll.h3
-rw-r--r--src/shared.h5
-rw-r--r--src/threadpool.c95
4 files changed, 107 insertions, 8 deletions
diff --git a/src/ll.c b/src/ll.c
index 9bb1441..285203d 100644
--- a/src/ll.c
+++ b/src/ll.c
@@ -196,4 +196,16 @@ int dlinkedlist_foreach(dlinkedlist *ll, int (*callback)(void*)) {
196 callback(p->data); 196 callback(p->data);
197 197
198 return 0; 198 return 0;
199}
200
201void * dlinkedlist_poplast(dlinkedlist *ll) {
202 if(!ll)
203 RETURNWERR(EINVAL, NULL);
204 if(dlinkedlist_isempty(ll))
205 RETURNWERR(ENODATA, NULL);
206
207 void *data = dlinkedlist_get(ll, ll->size - 1);
208 dlinkedlist_remove(ll, ll->size - 1);
209
210 return data;
199} \ No newline at end of file 211} \ No newline at end of file
diff --git a/src/ll.h b/src/ll.h
index 3636e77..4b5a2df 100644
--- a/src/ll.h
+++ b/src/ll.h
@@ -25,6 +25,7 @@ typedef void (*dll_freecb)(void*);
25typedef struct dlinked dlinkedlist; 25typedef struct dlinked dlinkedlist;
26 26
27#ifndef __VXGG_REWRITE___LL_INTERNAL___ 27#ifndef __VXGG_REWRITE___LL_INTERNAL___
28
28dlinkedlist * dlinkedlist_init(void); 29dlinkedlist * dlinkedlist_init(void);
29void dlinkedlist_free(dlinkedlist *ll); 30void dlinkedlist_free(dlinkedlist *ll);
30int dlinkedlist_append(dlinkedlist * const ll, void *data, dll_freecb fcb); 31int dlinkedlist_append(dlinkedlist * const ll, void *data, dll_freecb fcb);
@@ -32,11 +33,13 @@ int dlinkedlist_prepend(dlinkedlist * const ll, void *data, dll_freecb fcb);
32int dlinkedlist_insert(dlinkedlist * const ll, void *data, dll_freecb fcb, int index); 33int dlinkedlist_insert(dlinkedlist * const ll, void *data, dll_freecb fcb, int index);
33void* dlinkedlist_get(const dlinkedlist * const ll, int index); 34void* dlinkedlist_get(const dlinkedlist * const ll, int index);
34int dlinkedlist_remove(dlinkedlist * const ll, int index); 35int dlinkedlist_remove(dlinkedlist * const ll, int index);
36void * dlinkedlist_poplast(dlinkedlist *ll);
35 37
36int dlinkedlist_size(const dlinkedlist * const ll); 38int dlinkedlist_size(const dlinkedlist * const ll);
37#define dlinkedlist_isempty(ll) (dlinkedlist_size((ll)) == 0) 39#define dlinkedlist_isempty(ll) (dlinkedlist_size((ll)) == 0)
38 40
39int dlinkedlist_foreach(dlinkedlist *ll, int (*callback)(void*)); 41int dlinkedlist_foreach(dlinkedlist *ll, int (*callback)(void*));
42
40#endif 43#endif
41 44
42#endif \ No newline at end of file 45#endif \ No newline at end of file
diff --git a/src/shared.h b/src/shared.h
index 1a629e6..3b0a5f7 100644
--- a/src/shared.h
+++ b/src/shared.h
@@ -76,10 +76,13 @@ int cleanup_fire(cleanup * const loc);
76 76
77/* Cleanup environment creator. Automatically defines the variables `__CLEANUP`, `__CLEANUP_FUNCS`, and `__CLEANUP_ARGS` and initializes 77/* Cleanup environment creator. Automatically defines the variables `__CLEANUP`, `__CLEANUP_FUNCS`, and `__CLEANUP_ARGS` and initializes
78// via `cleanup_init()` using these variables. */ 78// via `cleanup_init()` using these variables. */
79#define cleanup_create(size) \ 79#define cleanup_CREATE(size) \
80cleanup __CLEANUP; \ 80cleanup __CLEANUP; \
81cleanup_callback __CLEANUP_FUNCS[(size)]; \ 81cleanup_callback __CLEANUP_FUNCS[(size)]; \
82void *__CLEANUP_ARGS[(size)]; \ 82void *__CLEANUP_ARGS[(size)]; \
83cleanup_init(&__CLEANUP, (size), __CLEANUP_FUNCS, __CLEANUP_ARGS) 83cleanup_init(&__CLEANUP, (size), __CLEANUP_FUNCS, __CLEANUP_ARGS)
84 84
85#define cleanup_REGISTER(cb, arg) cleanup_register(&__CLEANUP, (cb), (arg))
86#define cleanup_CNDREGISTER(flag, cb, arg) cleanup_cndregister(&__CLEANUP, (flag), (cb), (arg))
87
85#endif \ No newline at end of file 88#endif \ No newline at end of file
diff --git a/src/threadpool.c b/src/threadpool.c
index e230ebb..808dd5d 100644
--- a/src/threadpool.c
+++ b/src/threadpool.c
@@ -4,6 +4,7 @@
4 4
5#include "ll.h" 5#include "ll.h"
6 6
7#include <asm-generic/errno-base.h>
7#include <threads.h> 8#include <threads.h>
8#include <stdlib.h> 9#include <stdlib.h>
9#include <errno.h> 10#include <errno.h>
@@ -161,34 +162,34 @@ static void ___ucleanup_dll(void *dll) {
161 162
162cqueue * cqueue_init(int mtx_type) { 163cqueue * cqueue_init(int mtx_type) {
163 unsigned char flag = 0; 164 unsigned char flag = 0;
164 cleanup_create(10); 165 cleanup_CREATE(10);
165 166
166 cqueue *cq = VALLOC(1, sizeof(*cq)); 167 cqueue *cq = VALLOC(1, sizeof(*cq));
167 if(!cq) 168 if(!cq)
168 return NULL; 169 return NULL;
169 cleanup_register(&__CLEANUP, free, cq); 170 cleanup_REGISTER(free, cq);
170 171
171 cq->mutex = VALLOC(1, sizeof(*(cq->mutex))); 172 cq->mutex = VALLOC(1, sizeof(*(cq->mutex)));
172 if(!(cq->mutex)) 173 if(!(cq->mutex))
173 flag++; 174 flag++;
174 cleanup_cndregister(&__CLEANUP, flag, free, cq->mutex); 175 cleanup_CNDREGISTER(flag, free, cq->mutex);
175 176
176 if(!flag && mtx_init(cq->mutex, mtx_type) != thrd_success) 177 if(!flag && mtx_init(cq->mutex, mtx_type) != thrd_success)
177 flag++; 178 flag++;
178 cleanup_cndregister(&__CLEANUP, flag, ___ucleanup_mtxd, cq->mutex); 179 cleanup_CNDREGISTER(flag, ___ucleanup_mtxd, cq->mutex);
179 180
180 if(!flag && !(cq->conditional = VALLOC(1, sizeof(*(cq->conditional))))) 181 if(!flag && !(cq->conditional = VALLOC(1, sizeof(*(cq->conditional)))))
181 flag++; 182 flag++;
182 cleanup_cndregister(&__CLEANUP, flag, free, cq->conditional); 183 cleanup_CNDREGISTER(flag, free, cq->conditional);
183 184
184 if(!flag && cnd_init(cq->conditional) != thrd_success) 185 if(!flag && cnd_init(cq->conditional) != thrd_success)
185 flag++; 186 flag++;
186 cleanup_cndregister(&__CLEANUP, flag, ___ucleanup_cndd, cq->conditional); 187 cleanup_CNDREGISTER(flag, ___ucleanup_cndd, cq->conditional);
187 188
188 cq->list = dlinkedlist_init(); 189 cq->list = dlinkedlist_init();
189 if(!flag && !cq->list) 190 if(!flag && !cq->list)
190 flag++; 191 flag++;
191 cleanup_cndregister(&__CLEANUP, flag, ___ucleanup_dll, cq->list); 192 cleanup_CNDREGISTER(flag, ___ucleanup_dll, cq->list);
192 193
193 if(flag) 194 if(flag)
194 cleanup_fire(&__CLEANUP); 195 cleanup_fire(&__CLEANUP);
@@ -210,4 +211,84 @@ void cqueue_free(cqueue *cq) {
210 free(cq); 211 free(cq);
211 212
212 return; 213 return;
214}
215
216int cqueue_append(cqueue * const cq, task *tsk) {
217 if(!cq || !tsk)
218 RETURNWERR(EINVAL, -1);
219
220 mtx_lock(cq->mutex);
221 dlinkedlist_append(cq->list, tsk, free);
222 mtx_unlock(cq->mutex);
223 cnd_signal(cq->conditional);
224
225 return 0;
226}
227
228int cqueue_prepend(cqueue * const cq, task *tsk) {
229 if(!cq || !tsk)
230 RETURNWERR(EINVAL, -1);
231
232 mtx_lock(cq->mutex);
233 dlinkedlist_prepend(cq->list, tsk, free);
234 mtx_unlock(cq->mutex);
235 cnd_signal(cq->conditional);
236
237 return 0;
238}
239
240int cqueue_insert(cqueue * const cq, task *tsk, int index) {
241 if(!cq || !tsk || index < 0) // Can't check to see if the index is too high without locking the mutex first
242 RETURNWERR(EINVAL, -1);
243
244 mtx_lock(cq->mutex);
245 dlinkedlist_insert(cq->list, tsk, free, index);
246 mtx_unlock(cq->mutex);
247 cnd_signal(cq->conditional);
248
249 return 0;
250}
251
252int cqueue_size(cqueue const * const cq) {
253 if(!cq)
254 RETURNWERR(EINVAL, -1);
255
256 mtx_lock(cq->mutex);
257 int retval = dlinkedlist_size(cq->list);
258 mtx_unlock(cq->mutex);
259
260 return retval;
261}
262
263int cqueue_isempty(cqueue const * const cq) {
264 return (cqueue_size(cq) == 0);
265}
266
267int cqueue_trypop(cqueue * const cq, task **ret) {
268 if(!cq || !ret || !*ret)
269 RETURNWERR(EINVAL, -1);
270
271 int retval = 0;
272
273 mtx_lock(cq->mutex);
274 if(!dlinkedlist_isempty(cq->list)) {
275 *ret = (task*)dlinkedlist_poplast(cq->list);
276 retval = 1;
277 }
278 mtx_unlock(cq->mutex);
279
280 return retval;
281}
282
283int cqueue_waitpop(cqueue * const cq, task **ret) {
284 if(!cq || !ret || !*ret)
285 RETURNWERR(EINVAL, -1);
286
287 mtx_lock(cq->mutex);
288 while(!dlinkedlist_isempty(cq->list))
289 cnd_wait(cq->conditional, cq->mutex); // Unlocks mutex while waiting, acquires lock once waiting is done
290 *ret = dlinkedlist_poplast(cq->list);
291 mtx_unlock(cq->mutex);
292
293 return 0;
213} \ No newline at end of file 294} \ No newline at end of file