diff options
| author | @syxhe <https://t.me/syxhe> | 2025-05-14 12:19:34 -0500 |
|---|---|---|
| committer | @syxhe <https://t.me/syxhe> | 2025-05-14 12:19:34 -0500 |
| commit | 928238bdcbc78c4196eb4a3508808c79e31f7c84 (patch) | |
| tree | 6ce7c393be64ba26c54f9f5f8d3fa442c6f5833d | |
| parent | 9be8b5f26a29dad04035386331461c4c320f9237 (diff) | |
Update signatures of free-type functions to match the freecallback signature
| -rw-r--r-- | src/Makefile | 41 | ||||
| -rw-r--r-- | src/arena.c | 50 | ||||
| -rw-r--r-- | src/arena.h | 10 | ||||
| -rw-r--r-- | src/ll.c | 5 | ||||
| -rw-r--r-- | src/ll.h | 2 | ||||
| -rwxr-xr-x | src/main.c | 202 | ||||
| -rw-r--r-- | src/threadpool.c | 264 | ||||
| -rw-r--r-- | src/~Makefile | 39 |
8 files changed, 197 insertions, 416 deletions
diff --git a/src/Makefile b/src/Makefile index f89fd4d..b045807 100644 --- a/src/Makefile +++ b/src/Makefile | |||
| @@ -1,2 +1,39 @@ | |||
| 1 | all: | 1 | CC = gcc |
| 2 | @./main.c | 2 | SHELL := /usr/bin/env |
| 3 | .SHELLFLAGS := -S bash -c | ||
| 4 | |||
| 5 | # I need to get better at makefiles so I can write this in a way that isn't absolutely insane/stupid | ||
| 6 | # RELEASE_CFLAGS := -O3 -fipa-pta -fipa-cp -fuse-linker-plugin -flto=auto | ||
| 7 | # RELEASE_LDFLAGS := -fuse-linker-plugin -flto=auto | ||
| 8 | |||
| 9 | CFLAGS = -std=c2x -Wall -Wextra -Wpedantic -pedantic-errors -fanalyzer -Wanalyzer-too-complex -ggdb -g3 -O0 $$(pkg-config --cflags libsodium) | ||
| 10 | LDLIBS += $$(pkg-config --libs-only-l libsodium) | ||
| 11 | LDFLAGS += $$(pkg-config --libs-only-L libsodium) | ||
| 12 | DEPFLAGS = -MT $@ -MMD -MP -MF $*.d | ||
| 13 | |||
| 14 | SOURCES := $(wildcard *.c) | ||
| 15 | OBJECTS := $(patsubst %.c,%.o,$(SOURCES)) | ||
| 16 | DEPS := $(patsubst %.c,%.d,$(SOURCES)) | ||
| 17 | |||
| 18 | COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) -c | ||
| 19 | |||
| 20 | .PHONY: all c clean val | ||
| 21 | .DELETE_ON_ERROR: | ||
| 22 | .ONESHELL: | ||
| 23 | |||
| 24 | all: main | ||
| 25 | main: $(OBJECTS) | ||
| 26 | |||
| 27 | %.o: %.c %.d | ||
| 28 | $(COMPILE.c) $< | ||
| 29 | |||
| 30 | $(DEPS): | ||
| 31 | include $(wildcard $(DEPS)) | ||
| 32 | # Adopted from https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ | ||
| 33 | |||
| 34 | c clean: | ||
| 35 | @-rm -rv main $(OBJECTS) $(DEPS) $(wildcard *.test*) $(wildcard *.enc) | ||
| 36 | |||
| 37 | val: | ||
| 38 | $(MAKE) all | ||
| 39 | valgrind --leak-check=yes ./main \ No newline at end of file | ||
diff --git a/src/arena.c b/src/arena.c index f944661..40c72d5 100644 --- a/src/arena.c +++ b/src/arena.c | |||
| @@ -103,42 +103,25 @@ void * arena_alloc(arena * const arena, size_t bytes) { | |||
| 103 | // doesn't, that sucks and blows everything up | 103 | // doesn't, that sucks and blows everything up |
| 104 | } | 104 | } |
| 105 | 105 | ||
| 106 | int arena_free(arena **arena) { | 106 | void arena_free(void *a) { |
| 107 | if(!arena) | 107 | if(!a) |
| 108 | RETURNWERR(EINVAL, -1); | 108 | return; |
| 109 | if(!(*arena)) | ||
| 110 | RETURNWERR(EINVAL, -1); | ||
| 111 | 109 | ||
| 112 | (*arena)->current = (*arena)->start; | 110 | arena *real = (arena *)a; |
| 113 | for(arenanode *n; (*arena)->current != NULL;) { | 111 | real->current = real->start; |
| 114 | n = (*arena)->current->next; | 112 | for(arenanode *n; real->current != NULL;) { |
| 113 | n = real->current->next; | ||
| 115 | 114 | ||
| 116 | free((*arena)->current->membase); | 115 | free(real->current->membase); |
| 117 | free((*arena)->current); | 116 | free(real->current); |
| 118 | 117 | ||
| 119 | (*arena)->current = n; | 118 | real->current = n; |
| 120 | } | 119 | } |
| 121 | free((*arena)); | 120 | free(real); |
| 122 | (*arena) = NULL; | ||
| 123 | 121 | ||
| 124 | return 0; | 122 | return; |
| 125 | } | 123 | } |
| 126 | 124 | ||
| 127 | int arena_clear(arena **arena) { | ||
| 128 | if(!arena) | ||
| 129 | RETURNWERR(EINVAL, -1); | ||
| 130 | if(!(*arena)) | ||
| 131 | RETURNWERR(EINVAL, -1); | ||
| 132 | |||
| 133 | size_t bytes = (*arena)->node_memspace; | ||
| 134 | |||
| 135 | int ret = 0; | ||
| 136 | if((ret = arena_free(arena)) < 0) | ||
| 137 | return ret; | ||
| 138 | (*arena) = arena_init(bytes); | ||
| 139 | |||
| 140 | return (!(*arena)) ? -1 : 0; | ||
| 141 | } | ||
| 142 | 125 | ||
| 143 | 126 | ||
| 144 | 127 | ||
| @@ -158,10 +141,7 @@ void * simplearena_alloc(simplearena * const a, size_t bytes) { | |||
| 158 | return arena_alloc(a, bytes); | 141 | return arena_alloc(a, bytes); |
| 159 | } | 142 | } |
| 160 | 143 | ||
| 161 | int simplearena_free(simplearena **a) { | 144 | void simplearena_free(simplearena *a) { |
| 162 | return arena_free(a); | 145 | arena_free(a); |
| 163 | } | 146 | return; |
| 164 | |||
| 165 | int simplearena_clear(simplearena **a) { | ||
| 166 | return arena_clear(a); | ||
| 167 | } \ No newline at end of file | 147 | } \ No newline at end of file |
diff --git a/src/arena.h b/src/arena.h index 1c1c576..907a2fa 100644 --- a/src/arena.h +++ b/src/arena.h | |||
| @@ -26,10 +26,7 @@ arena * arena_init(size_t bytes); | |||
| 26 | void * arena_alloc(arena * const arena, size_t bytes); | 26 | void * arena_alloc(arena * const arena, size_t bytes); |
| 27 | 27 | ||
| 28 | // Free an arena its memory pool(s). Returns -1 and sets `errno` if the given arena is NULL | 28 | // Free an arena its memory pool(s). Returns -1 and sets `errno` if the given arena is NULL |
| 29 | int arena_free(arena **arena); | 29 | void arena_free(void *a); |
| 30 | |||
| 31 | // Clear an arena of its contents (frees and inits an arena in 1). Returns -1 and sets `errno` if the given arena is NULL | ||
| 32 | int arena_clear(arena **arena); | ||
| 33 | 30 | ||
| 34 | 31 | ||
| 35 | // Initializes a simple arena. | 32 | // Initializes a simple arena. |
| @@ -39,9 +36,6 @@ simplearena * simplearena_init(size_t bytes); | |||
| 39 | void * simplearena_alloc(simplearena * const a, size_t bytes); | 36 | void * simplearena_alloc(simplearena * const a, size_t bytes); |
| 40 | 37 | ||
| 41 | // Free a simple arena. Exits / returns -1 on error depending on the value of `___VXGG___USE_XALLOC_FOR_ARENAS___` | 38 | // Free a simple arena. Exits / returns -1 on error depending on the value of `___VXGG___USE_XALLOC_FOR_ARENAS___` |
| 42 | int simplearena_free(simplearena **a); | 39 | void simplearena_free(simplearena *a); |
| 43 | |||
| 44 | // Clear a simple arena and its memory pool (frees and inits a simple arena in 1). Exits / returns -1 on error depending on the value of `___VXGG___USE_XALLOC_FOR_ARENAS___` | ||
| 45 | int simplearena_clear(simplearena **a); | ||
| 46 | 40 | ||
| 47 | #endif \ No newline at end of file | 41 | #endif \ No newline at end of file |
| @@ -19,10 +19,11 @@ dlinkedlist * dlinkedlist_init(void) { | |||
| 19 | return ll; | 19 | return ll; |
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | void dlinkedlist_free(dlinkedlist *ll) { | 22 | void dlinkedlist_free(void *dll) { |
| 23 | if(!ll) | 23 | if(!dll) |
| 24 | return; | 24 | return; |
| 25 | 25 | ||
| 26 | dlinkedlist *ll = (dlinkedlist *)dll; | ||
| 26 | for(dllnode *current = ll->start, *next; current != NULL; ) { | 27 | for(dllnode *current = ll->start, *next; current != NULL; ) { |
| 27 | next = current->next; | 28 | next = current->next; |
| 28 | 29 | ||
| @@ -13,7 +13,7 @@ typedef struct dlinked dlinkedlist; | |||
| 13 | #ifndef __VXGG_REWRITE___LL_INTERNAL___ | 13 | #ifndef __VXGG_REWRITE___LL_INTERNAL___ |
| 14 | 14 | ||
| 15 | dlinkedlist * dlinkedlist_init(void); | 15 | dlinkedlist * dlinkedlist_init(void); |
| 16 | void dlinkedlist_free(dlinkedlist *ll); | 16 | void dlinkedlist_free(void *dll); |
| 17 | int dlinkedlist_append(dlinkedlist * const ll, void *data, dll_freecb fcb); | 17 | int dlinkedlist_append(dlinkedlist * const ll, void *data, dll_freecb fcb); |
| 18 | int dlinkedlist_prepend(dlinkedlist * const ll, void *data, dll_freecb fcb); | 18 | int dlinkedlist_prepend(dlinkedlist * const ll, void *data, dll_freecb fcb); |
| 19 | int dlinkedlist_insert(dlinkedlist * const ll, void *data, dll_freecb fcb, int index); | 19 | int dlinkedlist_insert(dlinkedlist * const ll, void *data, dll_freecb fcb, int index); |
| @@ -1,192 +1,14 @@ | |||
| 1 | ///usr/bin/true; gcc -std=c2x -Wall -Wextra -Wpedantic -pedantic-errors -fanalyzer -Wanalyzer-too-complex -ggdb -g3 -O0 main.c -o main && ./main; exit $? | 1 | #include "arena.h" |
| 2 | 2 | #include "encryption.h" | |
| 3 | #include <asm-generic/errno-base.h> | 3 | #include "ll.h" |
| 4 | #include <stdlib.h> | 4 | #include "scanner.h" |
| 5 | #include <errno.h> | 5 | #include "shared.h" |
| 6 | #include <error.h> | 6 | #include "threadpool.h" |
| 7 | #include <threads.h> | 7 | |
| 8 | 8 | #include "errno.h" | |
| 9 | #define RETURNWERR(eval, rval) do { \ | 9 | #include "error.h" |
| 10 | errno = (eval); \ | 10 | |
| 11 | return (rval); \ | 11 | int main() { |
| 12 | } while (0) | 12 | error(-1, ENOTSUP, "lol"); |
| 13 | |||
| 14 | #define ERROR(exitval, errval, msg, __VA_ARGS__) do { \ | ||
| 15 | error((exitval), (errval), (msg)__VA_ARGS__); \ | ||
| 16 | abort(); \ | ||
| 17 | } while (0) | ||
| 18 | |||
| 19 | void * xcalloc(size_t nmemb, size_t size) { | ||
| 20 | void *mem = calloc(nmemb, size); | ||
| 21 | if(!mem) | ||
| 22 | ERROR(-1, errno, "<xcalloc> failed to allocate memory ", ); | ||
| 23 | |||
| 24 | return mem; | ||
| 25 | } | ||
| 26 | |||
| 27 | |||
| 28 | |||
| 29 | typedef int (*gcallback)(void*); | ||
| 30 | typedef void (*fcallback)(void*); | ||
| 31 | typedef struct gdata { | ||
| 32 | void *data; | ||
| 33 | fcallback fcb; | ||
| 34 | } gdata; | ||
| 35 | |||
| 36 | gdata * gdata_init(void *data, fcallback fcb) { | ||
| 37 | gdata *gd = xcalloc(1, sizeof(*gd)); | ||
| 38 | gd->data = data; | ||
| 39 | gd->fcb = fcb; | ||
| 40 | |||
| 41 | return gd; | ||
| 42 | } | ||
| 43 | |||
| 44 | void gdata_free(void *gd) { | ||
| 45 | if(!gd) | ||
| 46 | return; | ||
| 47 | |||
| 48 | gdata *real = (gdata*)gd; | ||
| 49 | if(real->fcb != NULL) | ||
| 50 | real->fcb(real->data); | ||
| 51 | free(real); | ||
| 52 | |||
| 53 | return; | ||
| 54 | } | ||
| 55 | |||
| 56 | void * gdata_getdata(gdata * const gd) { | ||
| 57 | if(!gd) | ||
| 58 | RETURNWERR(EINVAL, NULL); | ||
| 59 | |||
| 60 | return gd->data; | ||
| 61 | } | ||
| 62 | |||
| 63 | void * gdata_destruct(gdata *gd) { | ||
| 64 | if(!gd) | ||
| 65 | RETURNWERR(EINVAL, NULL); | ||
| 66 | |||
| 67 | void *data = gdata_getdata(gd); | ||
| 68 | free(gd); | ||
| 69 | return data; | ||
| 70 | } | ||
| 71 | |||
| 72 | |||
| 73 | |||
| 74 | typedef struct stack { | ||
| 75 | gdata **arr; | ||
| 76 | int size; | ||
| 77 | int used; | ||
| 78 | } stack; | ||
| 79 | |||
| 80 | stack * stack_init(int size) { | ||
| 81 | if(size < 1) | ||
| 82 | RETURNWERR(EINVAL, NULL); | ||
| 83 | |||
| 84 | stack *st = xcalloc(1, sizeof(*st)); | ||
| 85 | st->size = size; | ||
| 86 | st->used = 0; | ||
| 87 | st->arr = xcalloc(st->size, sizeof(gdata*)); | ||
| 88 | |||
| 89 | return st; | ||
| 90 | } | ||
| 91 | |||
| 92 | void stack_free(void *st) { | ||
| 93 | if(!st) | ||
| 94 | return; | ||
| 95 | |||
| 96 | stack *real = (stack*)st; | ||
| 97 | for(int i = 0; i < real->used; i++) | ||
| 98 | gdata_free(real->arr[i]); | ||
| 99 | free(real->arr); | ||
| 100 | free(real); | ||
| 101 | |||
| 102 | return; | ||
| 103 | } | ||
| 104 | |||
| 105 | int stack_push(stack *st, gdata *gd) { | ||
| 106 | if(!st || !gd) | ||
| 107 | RETURNWERR(EINVAL, -1); | ||
| 108 | if(!(st->used < st->size)) | ||
| 109 | RETURNWERR(ENOMEM, 0); | ||
| 110 | |||
| 111 | st->arr[st->used++] = gd; | ||
| 112 | return st->used; | ||
| 113 | } | ||
| 114 | |||
| 115 | gdata * stack_pop(stack *st) { | ||
| 116 | if(!st) | ||
| 117 | RETURNWERR(EINVAL, NULL); | ||
| 118 | if(st->used <= 0) | ||
| 119 | RETURNWERR(ENODATA, 0); | ||
| 120 | |||
| 121 | return st->arr[--st->used]; | ||
| 122 | } | ||
| 123 | |||
| 124 | int stack_pushd(stack *st, void *data, fcallback fcb) { | ||
| 125 | if(!st) | ||
| 126 | RETURNWERR(EINVAL, -1); | ||
| 127 | |||
| 128 | gdata *gd = gdata_init(data, fcb); | ||
| 129 | int retval = stack_push(st, gd); | ||
| 130 | if(retval <= 0) | ||
| 131 | gdata_free(gd); | ||
| 132 | |||
| 133 | return retval; | ||
| 134 | } | ||
| 135 | |||
| 136 | void * stack_popd(stack *st) { | ||
| 137 | if(!st) | ||
| 138 | RETURNWERR(EINVAL, NULL); | ||
| 139 | |||
| 140 | gdata *gd = stack_pop(st); | ||
| 141 | if(!gd) | ||
| 142 | return NULL; | ||
| 143 | |||
| 144 | return gdata_destruct(gd); | ||
| 145 | } | ||
| 146 | |||
| 147 | |||
| 148 | |||
| 149 | typedef struct cstack { | ||
| 150 | stack *st; | ||
| 151 | mtx_t mutex; | ||
| 152 | cnd_t cond; | ||
| 153 | unsigned char canceled; | ||
| 154 | |||
| 155 | } cstack; | ||
| 156 | |||
| 157 | cstack * cstack_init(int size) { | ||
| 158 | if(size < 1) | ||
| 159 | RETURNWERR(EINVAL, NULL); | ||
| 160 | |||
| 161 | cstack *cst = xcalloc(1, sizeof(*cst)); | ||
| 162 | cst->st = stack_init(size); | ||
| 163 | cst->canceled = 0; | ||
| 164 | mtx_init(&cst->mutex, mtx_plain); | ||
| 165 | cnd_init(&cst->cond); | ||
| 166 | |||
| 167 | return cst; | ||
| 168 | } | ||
| 169 | |||
| 170 | int cstack_cancel(cstack * const cst) { | ||
| 171 | if(!cst) | ||
| 172 | RETURNWERR(EINVAL, -1); | ||
| 173 | |||
| 174 | mtx_lock(&cst->mutex); | ||
| 175 | cst->canceled = 1; | ||
| 176 | mtx_unlock(&cst->mutex); | ||
| 177 | cnd_broadcast(&cst->cond); | ||
| 178 | |||
| 179 | return 0; | 13 | return 0; |
| 180 | } | ||
| 181 | |||
| 182 | void cstack_free(void *cst) { | ||
| 183 | if(!cst) | ||
| 184 | return; | ||
| 185 | |||
| 186 | cstack *real = (cstack*)cst; | ||
| 187 | |||
| 188 | cstack_cancel(real); | ||
| 189 | // Ok I don't think there's a good way to wait for all threads to die without registering the threads | ||
| 190 | |||
| 191 | return; | ||
| 192 | } \ No newline at end of file | 14 | } \ No newline at end of file |
diff --git a/src/threadpool.c b/src/threadpool.c index 9d00030..e1c11aa 100644 --- a/src/threadpool.c +++ b/src/threadpool.c | |||
| @@ -10,7 +10,7 @@ | |||
| 10 | // Pair some data with a mutex. Specifically a way to deal with mutices easier, not for data storage (mtxpair_free does not free the `(void*)data` member) | 10 | // Pair some data with a mutex. Specifically a way to deal with mutices easier, not for data storage (mtxpair_free does not free the `(void*)data` member) |
| 11 | typedef struct mtxp { | 11 | typedef struct mtxp { |
| 12 | void *data; | 12 | void *data; |
| 13 | mtx_t *mtx; | 13 | mtx_t mtx; |
| 14 | } mtxpair; | 14 | } mtxpair; |
| 15 | 15 | ||
| 16 | mtxpair * mtxpair_init(void * const data, int type) { | 16 | mtxpair * mtxpair_init(void * const data, int type) { |
| @@ -18,16 +18,9 @@ mtxpair * mtxpair_init(void * const data, int type) { | |||
| 18 | if(!mtxp) | 18 | if(!mtxp) |
| 19 | return NULL; | 19 | return NULL; |
| 20 | 20 | ||
| 21 | // Make room for the mutex | ||
| 22 | mtxp->mtx = VALLOC(1, sizeof(*mtxp->mtx)); | ||
| 23 | if(!mtxp->mtx) { | ||
| 24 | free(mtxp); | ||
| 25 | return NULL; | ||
| 26 | } | ||
| 27 | |||
| 28 | // Init the mutex | 21 | // Init the mutex |
| 29 | if(mtx_init(mtxp->mtx, type) == thrd_error) { | 22 | if(mtx_init(&mtxp->mtx, type) == thrd_error) { |
| 30 | free(mtxp->mtx); free(mtxp); | 23 | free(mtxp); |
| 31 | RETURNWERR(errno, NULL); | 24 | RETURNWERR(errno, NULL); |
| 32 | } | 25 | } |
| 33 | 26 | ||
| @@ -39,8 +32,7 @@ void mtxpair_free(mtxpair *mp) { | |||
| 39 | if(!mp) | 32 | if(!mp) |
| 40 | return; | 33 | return; |
| 41 | 34 | ||
| 42 | mtx_destroy(mp->mtx); | 35 | mtx_destroy(&mp->mtx); |
| 43 | free(mp->mtx); | ||
| 44 | free(mp); | 36 | free(mp); |
| 45 | 37 | ||
| 46 | return; | 38 | return; |
| @@ -64,9 +56,9 @@ int thrd_createwmx(thrd_t * const thr, thrd_start_t func, mtxpair * const mtxd) | |||
| 64 | if(!mtxd) | 56 | if(!mtxd) |
| 65 | RETURNWERR(EINVAL, thrd_error); | 57 | RETURNWERR(EINVAL, thrd_error); |
| 66 | 58 | ||
| 67 | if(mtx_lock(mtxd->mtx) == thrd_error) {RETURNWERR(errno, thrd_error);} | 59 | if(mtx_lock(&mtxd->mtx) == thrd_error) {RETURNWERR(errno, thrd_error);} |
| 68 | int retval = thrd_create(thr, func, mtxd->data); | 60 | int retval = thrd_create(thr, func, mtxd->data); |
| 69 | if(mtx_unlock(mtxd->mtx) == thrd_error) {RETURNWERR(errno, thrd_error);} | 61 | if(mtx_unlock(&mtxd->mtx) == thrd_error) {RETURNWERR(errno, thrd_error);} |
| 70 | 62 | ||
| 71 | return retval; | 63 | return retval; |
| 72 | } | 64 | } |
| @@ -99,21 +91,6 @@ typedef struct task { | |||
| 99 | void *arg; | 91 | void *arg; |
| 100 | } task; | 92 | } task; |
| 101 | 93 | ||
| 102 | typedef struct cq { | ||
| 103 | dlinkedlist *list; | ||
| 104 | mtx_t *mtx; | ||
| 105 | cnd_t *cnd; | ||
| 106 | unsigned char canceled; | ||
| 107 | } cqueue; | ||
| 108 | |||
| 109 | typedef struct tp { | ||
| 110 | thrd_t **threads; | ||
| 111 | int nthreads; | ||
| 112 | |||
| 113 | cqueue *taskqueue; | ||
| 114 | } threadpool; | ||
| 115 | |||
| 116 | |||
| 117 | task * task_init(task_callback cb, void *arg) { | 94 | task * task_init(task_callback cb, void *arg) { |
| 118 | if(cb == NULL) | 95 | if(cb == NULL) |
| 119 | RETURNWERR(EINVAL, NULL); | 96 | RETURNWERR(EINVAL, NULL); |
| @@ -138,149 +115,158 @@ void task_free(task *ts) { | |||
| 138 | int task_fire(task *ts) { | 115 | int task_fire(task *ts) { |
| 139 | if(!ts) | 116 | if(!ts) |
| 140 | RETURNWERR(EINVAL, -1); | 117 | RETURNWERR(EINVAL, -1); |
| 118 | if(ts->cb == NULL) | ||
| 119 | RETURNWERR(EINVAL, -1); | ||
| 141 | 120 | ||
| 142 | return ts->cb(ts->arg); | 121 | return ts->cb(ts->arg); |
| 143 | } | 122 | } |
| 144 | 123 | ||
| 145 | 124 | ||
| 146 | /* Mutex: Lock a shared resource. Used to prevent race conditions when accessing / modifying some shared resource. A lock must | ||
| 147 | // always be followed by an unlock | ||
| 148 | 125 | ||
| 149 | // Semaphore: Send / wait on a signal; solves the consumer/producer problem. A function that sends should never wait, and a | 126 | typedef struct cq { |
| 150 | // function that waits should never send */ | 127 | dlinkedlist *taskqueue; |
| 128 | dlinkedlist *rthreads; | ||
| 151 | 129 | ||
| 152 | static void ___ucleanup_dfree(void *dll) { | 130 | mtx_t mtx; |
| 153 | if(!dll) | 131 | cnd_t cnd; |
| 154 | return; | 132 | |
| 133 | unsigned char canceled; | ||
| 155 | 134 | ||
| 156 | dlinkedlist_free((dlinkedlist *)dll); | 135 | } cqueue; |
| 157 | return; | ||
| 158 | } | ||
| 159 | 136 | ||
| 160 | static void ___ucleanup_cndd(void *cnd) { | ||
| 161 | if(!cnd) | ||
| 162 | return; | ||
| 163 | 137 | ||
| 164 | cnd_destroy((cnd_t *)cnd); | ||
| 165 | return; | ||
| 166 | } | ||
| 167 | 138 | ||
| 168 | static void ___ucleanup_mtxd(void *mtx) { | 139 | // static void ___ucleanup_dfree(void *dll) { |
| 169 | if(!mtx) | 140 | // if(!dll) |
| 170 | return; | 141 | // return; |
| 171 | 142 | ||
| 172 | mtx_destroy((mtx_t*)mtx); | 143 | // dlinkedlist_free((dlinkedlist *)dll); |
| 173 | return; | 144 | // return; |
| 174 | } | 145 | // } |
| 146 | |||
| 147 | // static void ___ucleanup_cndd(void *cnd) { | ||
| 148 | // if(!cnd) | ||
| 149 | // return; | ||
| 150 | |||
| 151 | // cnd_destroy((cnd_t *)cnd); | ||
| 152 | // return; | ||
| 153 | // } | ||
| 154 | |||
| 155 | // static void ___ucleanup_mtxd(void *mtx) { | ||
| 156 | // if(!mtx) | ||
| 157 | // return; | ||
| 175 | 158 | ||
| 176 | cqueue * cqueue_init(int mtx_type) { | 159 | // mtx_destroy((mtx_t*)mtx); |
| 177 | cleanup_CREATE(10); | 160 | // return; |
| 161 | // } | ||
| 162 | |||
| 163 | // cqueue * cqueue_init(int mtx_type) { | ||
| 164 | // cleanup_CREATE(10); | ||
| 178 | 165 | ||
| 179 | cqueue *cq = VALLOC(1, sizeof(*cq)); | 166 | // cqueue *cq = VALLOC(1, sizeof(*cq)); |
| 180 | if(!cq) | 167 | // if(!cq) |
| 181 | return NULL; | 168 | // return NULL; |
| 182 | cleanup_REGISTER(free, cq); | 169 | // cleanup_REGISTER(free, cq); |
| 183 | 170 | ||
| 184 | cq->canceled = FALSE; | 171 | // cq->canceled = FALSE; |
| 185 | cq->list = dlinkedlist_init(); | 172 | // cq->list = dlinkedlist_init(); |
| 186 | if(!cq->list) | 173 | // if(!cq->list) |
| 187 | cleanup_MARK(); | 174 | // cleanup_MARK(); |
| 188 | cleanup_CNDREGISTER(___ucleanup_dfree, cq->list); | 175 | // cleanup_CNDREGISTER(___ucleanup_dfree, cq->list); |
| 189 | |||
| 190 | if(!cleanup_ERRORFLAGGED) | ||
| 191 | if(!(cq->cnd = VALLOC(1, sizeof(*cq->cnd)))) | ||
| 192 | cleanup_MARK(); | ||
| 193 | cleanup_CNDREGISTER(free, cq->cnd); | ||
| 194 | 176 | ||
| 195 | if(!cleanup_ERRORFLAGGED) | 177 | // if(!cleanup_ERRORFLAGGED) |
| 196 | if(cnd_init(cq->cnd) == thrd_error) | 178 | // if(cnd_init(&cq->cnd) == thrd_error) |
| 197 | cleanup_MARK(); | 179 | // cleanup_MARK(); |
| 198 | cleanup_CNDREGISTER(___ucleanup_cndd, cq->cnd); | 180 | // cleanup_CNDREGISTER(___ucleanup_cndd, &cq->cnd); |
| 199 | 181 | ||
| 200 | if(!cleanup_ERRORFLAGGED) | 182 | // if(!cleanup_ERRORFLAGGED) |
| 201 | if(!(cq->mtx = VALLOC(1, sizeof(*cq->mtx)))) | 183 | // if(mtx_init(&cq->mtx, mtx_type) != thrd_success) |
| 202 | cleanup_MARK(); | 184 | // cleanup_MARK(); |
| 203 | cleanup_CNDREGISTER(free, cq->mtx); | 185 | // cleanup_CNDREGISTER(___ucleanup_mtxd, &cq->mtx); |
| 204 | |||
| 205 | if(!cleanup_ERRORFLAGGED) | ||
| 206 | if(mtx_init(cq->mtx, mtx_type) != thrd_success) | ||
| 207 | cleanup_MARK(); | ||
| 208 | cleanup_CNDREGISTER(___ucleanup_mtxd, cq->mtx); | ||
| 209 | 186 | ||
| 210 | if(cleanup_ERRORFLAGGED) | 187 | // if(cleanup_ERRORFLAGGED) |
| 211 | cleanup_FIRE(); | 188 | // cleanup_FIRE(); |
| 212 | 189 | ||
| 213 | return cq; | 190 | // return cq; |
| 214 | } | 191 | // } |
| 215 | 192 | ||
| 216 | void cqueue_cancel(cqueue *cq) { | 193 | // void cqueue_cancel(cqueue *cq) { |
| 217 | if(!cq) | 194 | // if(!cq) |
| 218 | return; | 195 | // return; |
| 219 | 196 | ||
| 220 | mtx_lock(cq->mtx); | 197 | // mtx_lock(cq->mtx); |
| 221 | if(cq->canceled) { | 198 | // if(cq->canceled) { |
| 222 | mtx_unlock(cq->mtx); | 199 | // mtx_unlock(cq->mtx); |
| 223 | thrd_exit(-1); | 200 | // thrd_exit(-1); |
| 224 | } | 201 | // } |
| 225 | 202 | ||
| 226 | cq->canceled++; | 203 | // cq->canceled++; |
| 227 | mtx_unlock(cq->mtx); | 204 | // mtx_unlock(cq->mtx); |
| 228 | cnd_broadcast(cq->cnd); | 205 | // cnd_broadcast(cq->cnd); |
| 229 | 206 | ||
| 230 | return; | 207 | // return; |
| 231 | } | 208 | // } |
| 232 | 209 | ||
| 233 | void cqueue_free(cqueue *cq) { | 210 | // void cqueue_free(cqueue *cq) { |
| 234 | if(!cq) | 211 | // if(!cq) |
| 235 | return; | 212 | // return; |
| 236 | 213 | ||
| 237 | cqueue_cancel(cq); | 214 | // cqueue_cancel(cq); |
| 238 | mtx_destroy(cq->mtx); | 215 | // mtx_destroy(cq->mtx); |
| 239 | cnd_destroy(cq->cnd); | 216 | // cnd_destroy(cq->cnd); |
| 240 | free(cq->mtx); | 217 | // free(cq->mtx); |
| 241 | free(cq->cnd); | 218 | // free(cq->cnd); |
| 242 | dlinkedlist_free(cq->list); | 219 | // dlinkedlist_free(cq->list); |
| 243 | 220 | ||
| 244 | return; | 221 | // return; |
| 245 | } | 222 | // } |
| 246 | 223 | ||
| 247 | int cqueue_addtask(cqueue * const cq, task * const tsk) { | 224 | // int cqueue_addtask(cqueue * const cq, task * const tsk) { |
| 248 | if(!cq || !tsk) | 225 | // if(!cq || !tsk) |
| 249 | RETURNWERR(EINVAL, -1); | 226 | // RETURNWERR(EINVAL, -1); |
| 250 | 227 | ||
| 251 | mtx_lock(cq->mtx); | 228 | // mtx_lock(cq->mtx); |
| 252 | 229 | ||
| 253 | // TODO: Think about creating an "exception" via signal handling | 230 | // // TODO: Think about creating an "exception" via signal handling |
| 254 | if(cq->canceled) { | 231 | // if(cq->canceled) { |
| 255 | mtx_unlock(cq->mtx); | 232 | // mtx_unlock(cq->mtx); |
| 256 | thrd_exit(-1); | 233 | // thrd_exit(-1); |
| 257 | } | 234 | // } |
| 258 | 235 | ||
| 259 | dlinkedlist_prepend(cq->list, tsk, free); | 236 | // dlinkedlist_prepend(cq->list, tsk, free); |
| 260 | mtx_unlock(cq->mtx); | 237 | // mtx_unlock(cq->mtx); |
| 261 | cnd_signal(cq->cnd); | 238 | // cnd_signal(cq->cnd); |
| 262 | 239 | ||
| 263 | return 0; | 240 | // return 0; |
| 264 | } | 241 | // } |
| 265 | 242 | ||
| 266 | task * cqueue_waitpop(cqueue * const cq) { | 243 | // task * cqueue_waitpop(cqueue * const cq) { |
| 267 | if(!cq) | 244 | // if(!cq) |
| 268 | RETURNWERR(EINVAL, NULL); | 245 | // RETURNWERR(EINVAL, NULL); |
| 269 | 246 | ||
| 270 | task *retval = NULL; | 247 | // task *retval = NULL; |
| 271 | 248 | ||
| 272 | mtx_lock(cq->mtx); | 249 | // mtx_lock(cq->mtx); |
| 273 | while(dlinkedlist_isempty(cq->list) && !cq->canceled) | 250 | // while(dlinkedlist_isempty(cq->list) && !cq->canceled) |
| 274 | cnd_wait(cq->cnd, cq->mtx); | 251 | // cnd_wait(cq->cnd, cq->mtx); |
| 275 | 252 | ||
| 276 | if(cq->canceled) { | 253 | // if(cq->canceled) { |
| 277 | mtx_unlock(cq->mtx); | 254 | // mtx_unlock(cq->mtx); |
| 278 | thrd_exit(-1); | 255 | // thrd_exit(-1); |
| 279 | } | 256 | // } |
| 280 | 257 | ||
| 281 | retval = dlinkedlist_get(cq->list, dlinkedlist_size(cq->list) - 1); | 258 | // retval = dlinkedlist_get(cq->list, dlinkedlist_size(cq->list) - 1); |
| 282 | dlinkedlist_remove(cq->list, dlinkedlist_size(cq->list) - 1); | 259 | // dlinkedlist_remove(cq->list, dlinkedlist_size(cq->list) - 1); |
| 283 | mtx_unlock(cq->mtx); | 260 | // mtx_unlock(cq->mtx); |
| 284 | 261 | ||
| 285 | return retval; | 262 | // return retval; |
| 286 | } \ No newline at end of file | 263 | // } |
| 264 | |||
| 265 | |||
| 266 | |||
| 267 | typedef struct tp { | ||
| 268 | thrd_t **threads; // thrd_t *threads[] | ||
| 269 | int nthreads; | ||
| 270 | |||
| 271 | cqueue *taskqueue; | ||
| 272 | } threadpool; | ||
diff --git a/src/~Makefile b/src/~Makefile deleted file mode 100644 index b045807..0000000 --- a/src/~Makefile +++ /dev/null | |||
| @@ -1,39 +0,0 @@ | |||
| 1 | CC = gcc | ||
| 2 | SHELL := /usr/bin/env | ||
| 3 | .SHELLFLAGS := -S bash -c | ||
| 4 | |||
| 5 | # I need to get better at makefiles so I can write this in a way that isn't absolutely insane/stupid | ||
| 6 | # RELEASE_CFLAGS := -O3 -fipa-pta -fipa-cp -fuse-linker-plugin -flto=auto | ||
| 7 | # RELEASE_LDFLAGS := -fuse-linker-plugin -flto=auto | ||
| 8 | |||
| 9 | CFLAGS = -std=c2x -Wall -Wextra -Wpedantic -pedantic-errors -fanalyzer -Wanalyzer-too-complex -ggdb -g3 -O0 $$(pkg-config --cflags libsodium) | ||
| 10 | LDLIBS += $$(pkg-config --libs-only-l libsodium) | ||
| 11 | LDFLAGS += $$(pkg-config --libs-only-L libsodium) | ||
| 12 | DEPFLAGS = -MT $@ -MMD -MP -MF $*.d | ||
| 13 | |||
| 14 | SOURCES := $(wildcard *.c) | ||
| 15 | OBJECTS := $(patsubst %.c,%.o,$(SOURCES)) | ||
| 16 | DEPS := $(patsubst %.c,%.d,$(SOURCES)) | ||
| 17 | |||
| 18 | COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) -c | ||
| 19 | |||
| 20 | .PHONY: all c clean val | ||
| 21 | .DELETE_ON_ERROR: | ||
| 22 | .ONESHELL: | ||
| 23 | |||
| 24 | all: main | ||
| 25 | main: $(OBJECTS) | ||
| 26 | |||
| 27 | %.o: %.c %.d | ||
| 28 | $(COMPILE.c) $< | ||
| 29 | |||
| 30 | $(DEPS): | ||
| 31 | include $(wildcard $(DEPS)) | ||
| 32 | # Adopted from https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ | ||
| 33 | |||
| 34 | c clean: | ||
| 35 | @-rm -rv main $(OBJECTS) $(DEPS) $(wildcard *.test*) $(wildcard *.enc) | ||
| 36 | |||
| 37 | val: | ||
| 38 | $(MAKE) all | ||
| 39 | valgrind --leak-check=yes ./main \ No newline at end of file | ||
