From 9be8b5f26a29dad04035386331461c4c320f9237 Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Thu, 8 May 2025 17:49:16 -0500 Subject: kms immediately --- src/main.c | 273 ++++++++++++++++++------------------------------------------- 1 file changed, 79 insertions(+), 194 deletions(-) (limited to 'src') diff --git a/src/main.c b/src/main.c index c885c5e..9d1c5ab 100755 --- a/src/main.c +++ b/src/main.c @@ -1,71 +1,72 @@ ///usr/bin/true; gcc -std=c2x -Wall -Wextra -Wpedantic -pedantic-errors -fanalyzer -Wanalyzer-too-complex -ggdb -g3 -O0 main.c -o main && ./main; exit $? -// #include -// #include -// #include -// #include -// #include -// #include - +#include #include #include -#include -#include -#include +#include #include +#define RETURNWERR(eval, rval) do { \ + errno = (eval); \ + return (rval); \ +} while (0) + +#define ERROR(exitval, errval, msg, __VA_ARGS__) do { \ + error((exitval), (errval), (msg)__VA_ARGS__); \ + abort(); \ +} while (0) void * xcalloc(size_t nmemb, size_t size) { void *mem = calloc(nmemb, size); if(!mem) - abort(); + ERROR(-1, errno, " failed to allocate memory ", ); return mem; } +typedef int (*gcallback)(void*); typedef void (*fcallback)(void*); typedef struct gdata { void *data; - fcallback freer; + fcallback fcb; } gdata; gdata * gdata_init(void *data, fcallback fcb) { gdata *gd = xcalloc(1, sizeof(*gd)); gd->data = data; - gd->freer = fcb; + gd->fcb = fcb; return gd; } -void gdata_free(gdata *gd) { +void gdata_free(void *gd) { if(!gd) return; - if(gd->freer != NULL) - gd->freer(gd->data); - free(gd); + gdata *real = (gdata*)gd; + if(real->fcb != NULL) + real->fcb(real->data); + free(real); return; } void * gdata_getdata(gdata * const gd) { - if(!gd) { - errno = EINVAL; - return NULL; - } - + if(!gd) + RETURNWERR(EINVAL, NULL); + return gd->data; } -void gdata_destruct(gdata *gd, void **storage) { - if(!gd || !storage) - return; +void * gdata_destruct(gdata *gd) { + if(!gd) + RETURNWERR(EINVAL, NULL); - *storage = gd->data; + void *data = gdata_getdata(gd); free(gd); - return; + return data; } @@ -78,7 +79,7 @@ typedef struct stack { stack * stack_init(int size) { if(size < 1) - return NULL; + RETURNWERR(EINVAL, NULL); stack *st = xcalloc(1, sizeof(*st)); st->size = size; @@ -88,220 +89,104 @@ stack * stack_init(int size) { return st; } -void stack_free(stack *st) { +void stack_free(void *st) { if(!st) return; - for(int i = 0; i < st->used; i++) - gdata_free(st->arr[i]); - free(st->arr); - free(st); - + stack *real = (stack*)st; + for(int i = 0; i < real->used; i++) + gdata_free(real->arr[i]); + free(real->arr); + free(real); + return; } -int stack_getsize(stack * const st) { - if(!st) - return -1; +int stack_push(stack *st, gdata *gd) { + if(!st || !gd) + RETURNWERR(EINVAL, -1); + if(!(st->used < st->size)) + RETURNWERR(ENOMEM, 0); - return st->size; + st->arr[st->used++] = gd; + return st->used; } -int stack_hasroom(stack * const st) { +gdata * stack_pop(stack *st) { if(!st) - return -1; - - return (st->used < st->size); -} - -int stack_push(stack *st, gdata *data) { - if(!st || !data) - return -1; - if(!stack_hasroom(st)) - return 0; - - st->arr[st->used++] = data; + RETURNWERR(EINVAL, NULL); + if(st->used <= 0) + RETURNWERR(ENODATA, 0); - return st->used; + return st->arr[--st->used]; } int stack_pushd(stack *st, void *data, fcallback fcb) { if(!st) - return -1; - if(!stack_hasroom(st)) - return 0; - + RETURNWERR(EINVAL, -1); + gdata *gd = gdata_init(data, fcb); int retval = stack_push(st, gd); - if(!(retval > 0)) + if(retval <= 0) gdata_free(gd); return retval; } -gdata * stack_pop(stack *st) { +void * stack_popd(stack *st) { if(!st) - return NULL; - if(st->used <= 0) - return NULL; + RETURNWERR(EINVAL, NULL); - gdata *gd = st->arr[--st->used]; - return gd; -} - -void * stack_popd(stack *st) { gdata *gd = stack_pop(st); - void *data = NULL; - - gdata_destruct(gd, &data); - return data; + if(!gd) + return NULL; + + return gdata_destruct(gd); } typedef struct cstack { - stack *stack; + stack *st; mtx_t mutex; cnd_t cond; unsigned char canceled; + } cstack; cstack * cstack_init(int size) { if(size < 1) - return NULL; + RETURNWERR(EINVAL, NULL); - cstack *cs = xcalloc(1, sizeof(*cs)); - cs->canceled = 0; - cs->stack = stack_init(size); - mtx_init(&cs->mutex, mtx_plain); - cnd_init(&cs->cond); + cstack *cst = xcalloc(1, sizeof(*cst)); + cst->st = stack_init(size); + cst->canceled = 0; + mtx_init(&cst->mutex, mtx_plain); + cnd_init(&cst->cond); - return cs; + return cst; } -int cstack_cancel(cstack *cs) { - if(!cs) - return -1; +int cstack_cancel(cstack * const cst) { + if(!cst) + RETURNWERR(EINVAL, -1); - mtx_lock(&cs->mutex); - cs->canceled = 1; - mtx_unlock(&cs->mutex); - cnd_broadcast(&cs->cond); + mtx_lock(&cst->mutex); + cst->canceled = 1; + mtx_unlock(&cst->mutex); + cnd_broadcast(&cst->cond); return 0; } -void cstack_free(cstack *cs) { - if(!cs) +void cstack_free(void *cst) { + if(!cst) return; - cstack_cancel(cs); - stack_free(cs->stack); - mtx_destroy(&cs->mutex); - cnd_destroy(&cs->cond); - - return; -} - -int cstack_push(cstack *cs, gdata *data) { - if(!cs || !data) - return -1; - - mtx_lock(&cs->mutex); - stack_push(cs->stack, data); - mtx_unlock(&cs->mutex); - cnd_signal(&cs->cond); - - return 0; -} - -int cstack_pushd(cstack *cs, void *data, fcallback fcb) { - if(!cs) - return -1; - - mtx_lock(&cs->mutex); - stack_pushd(cs->stack, data, fcb); - mtx_unlock(&cs->mutex); - cnd_signal(&cs->cond); - - return 0; -} - -gdata * cstack_pop(cstack *cs) { - if(!cs) - return NULL; - - gdata *gd = NULL; - int csize = -1; - - mtx_lock(&cs->mutex); - - // Wait until there's data to pop or the thing gets canceled - for(; (csize = stack_getsize(cs->stack)) == 0 || !cs->canceled;) - cnd_wait(&cs->cond, &cs->mutex); - - // If the stack was canceled, or there's an error, exit - if(cs->canceled || csize < 0) - thrd_exit(-1); - - // Otherwise, there's data, of which pop it to gd - gd = stack_pop(cs->stack); - - mtx_unlock(&cs->mutex); - - return gd; -} - -void * cstack_popd(cstack *cs) { - if(!cs) - return NULL; - - gdata *gd = NULL; - int csize = -1; - - mtx_lock(&cs->mutex); - - // Wait until there's data to pop or the thing gets canceled - for(; (csize = stack_getsize(cs->stack)) == 0 || !cs->canceled;) - cnd_wait(&cs->cond, &cs->mutex); + cstack *real = (cstack*)cst; - // If the stack was canceled, or there's an error, exit - if(cs->canceled || csize < 0) - thrd_exit(-1); - - // Otherwise, there's data, of which pop it to gd - gd = stack_pop(cs->stack); - - mtx_unlock(&cs->mutex); - - void *realdata = NULL; - gdata_destruct(gd, &realdata); - - return realdata; -} + cstack_cancel(real); + // Ok I don't think there's a good way to wait for all threads to die without registering the threads - - -int main() { - // stack *st = stack_init(10); - // stack_pushd(st, (void*)10, NULL); - // stack_pushd(st, (void*)11, NULL); - // stack_pushd(st, (void*)12, NULL); - // stack_pushd(st, strdup("This is some data"), free); - - // char *data = stack_popd(st); - // printf("%s\n", (data) ? data : "null"); - // free(data); - - // stack_free(st); - - cstack *cst = cstack_init(10); - cstack_pushd(cst, (void*)10, NULL); - cstack_pushd(cst, (void*)11, NULL); - cstack_pushd(cst, (void*)12, NULL); - cstack_pushd(cst, (void*)strdup("This is some data"), free); - - cstack_free(cst); - - return 0; + return; } \ No newline at end of file -- cgit v1.2.3