diff options
Diffstat (limited to 'src/threadpool.c')
| -rw-r--r-- | src/threadpool.c | 95 |
1 files changed, 88 insertions, 7 deletions
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 | ||
| 162 | cqueue * cqueue_init(int mtx_type) { | 163 | cqueue * 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 | |||
| 216 | int 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 | |||
| 228 | int 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 | |||
| 240 | int 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 | |||
| 252 | int 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 | |||
| 263 | int cqueue_isempty(cqueue const * const cq) { | ||
| 264 | return (cqueue_size(cq) == 0); | ||
| 265 | } | ||
| 266 | |||
| 267 | int 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 | |||
| 283 | int 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 |
