From e68bb9339728134d780293bcda34ddbde633342a Mon Sep 17 00:00:00 2001 From: "@syxhe" Date: Wed, 7 May 2025 21:19:23 -0500 Subject: Simple stack implementation for making a concurrent stack --- src/Makefile | 41 +----------- src/main.c | 211 ++++++++++++++++++++++++++++++++++++---------------------- src/~Makefile | 39 +++++++++++ 3 files changed, 171 insertions(+), 120 deletions(-) mode change 100644 => 100755 src/main.c create mode 100644 src/~Makefile (limited to 'src') diff --git a/src/Makefile b/src/Makefile index b045807..f89fd4d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,39 +1,2 @@ -CC = gcc -SHELL := /usr/bin/env -.SHELLFLAGS := -S bash -c - -# I need to get better at makefiles so I can write this in a way that isn't absolutely insane/stupid -# RELEASE_CFLAGS := -O3 -fipa-pta -fipa-cp -fuse-linker-plugin -flto=auto -# RELEASE_LDFLAGS := -fuse-linker-plugin -flto=auto - -CFLAGS = -std=c2x -Wall -Wextra -Wpedantic -pedantic-errors -fanalyzer -Wanalyzer-too-complex -ggdb -g3 -O0 $$(pkg-config --cflags libsodium) -LDLIBS += $$(pkg-config --libs-only-l libsodium) -LDFLAGS += $$(pkg-config --libs-only-L libsodium) -DEPFLAGS = -MT $@ -MMD -MP -MF $*.d - -SOURCES := $(wildcard *.c) -OBJECTS := $(patsubst %.c,%.o,$(SOURCES)) -DEPS := $(patsubst %.c,%.d,$(SOURCES)) - -COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) -c - -.PHONY: all c clean val -.DELETE_ON_ERROR: -.ONESHELL: - -all: main -main: $(OBJECTS) - -%.o: %.c %.d - $(COMPILE.c) $< - -$(DEPS): -include $(wildcard $(DEPS)) -# Adopted from https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ - -c clean: - @-rm -rv main $(OBJECTS) $(DEPS) $(wildcard *.test*) $(wildcard *.enc) - -val: - $(MAKE) all - valgrind --leak-check=yes ./main \ No newline at end of file +all: + @./main.c diff --git a/src/main.c b/src/main.c old mode 100644 new mode 100755 index d1048f0..e08b964 --- a/src/main.c +++ b/src/main.c @@ -1,103 +1,152 @@ -#include "arena.h" -#include "ll.h" -#include "encryption.h" -#include "scanner.h" -#include "shared.h" -#include "threadpool.h" +///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 -typedef int (*thingcb)(void*); -struct thing { - thingcb cb; - void *arg; -}; -typedef struct queue { - mtx_t *cqmutex; - cnd_t *cqcnd; - unsigned char cstatus; - - int len; - int used; - - struct thing **queue; -} ccqueue; +void * xcalloc(size_t nmemb, size_t size) { + void *mem = calloc(nmemb, size); + if(!mem) + abort(); + + return mem; +} -#define QUEUE_LEN 10 -int consumer(void *queue) { - if(!queue) - thrd_exit(-1); - ccqueue *real = (ccqueue *)queue; - for(struct thing *thing = NULL;;) { - cnd_wait(real->cqcnd, real->cqmutex); - if(real->cstatus) - thrd_exit(-1); +typedef void (*fcallback)(void*); +typedef struct gdata { + void *data; + fcallback freer; +} gdata; + +gdata * gdata_init(void *data, fcallback fcb) { + gdata *gd = xcalloc(1, sizeof(*gd)); + gd->data = data; + gd->freer = fcb; + + return gd; +} + +void gdata_free(gdata *gd) { + if(!gd) + return; + + if(gd->freer != NULL) + gd->freer(gd->data); + free(gd); - if(real->used > 0) { - thing = real->queue[real->used - 1]; - real->used--; - } + return; +} - if(thing != NULL) - if(thing->arg != NULL) - thing->cb(thing->arg); +void * gdata_getdata(gdata * const gd) { + if(!gd) { + errno = EINVAL; + return NULL; } + + return gd->data; +} - thrd_exit(0); +void gdata_destruct(gdata *gd, void **storage) { + if(!gd || !storage) + return; + + *storage = gd->data; + free(gd); + return; } -int testcb(void *data) { - if(!data) - return -1; - printf("%s\n", (char*)data); - return 0; + +typedef struct stack { + gdata **arr; + int size; + int used; +} stack; + +stack * stack_init(int size) { + if(size < 1) + return NULL; + + stack *st = xcalloc(1, sizeof(*st)); + st->size = size; + st->used = 0; + st->arr = xcalloc(st->size, sizeof(gdata*)); + + return st; } -int main() { - // error(1, ENOTSUP, "No main file lol"); - - // Manually implement a threadpool and consumer in a "dumb" way to make sure I'm doing the correct thing - ccqueue *cqueue = xcalloc(1, sizeof(*cqueue)); - cqueue->cqmutex = xcalloc(1, sizeof(*cqueue->cqmutex)); mtx_init(cqueue->cqmutex, mtx_plain); - cqueue->cqcnd = xcalloc(1, sizeof(*cqueue->cqcnd)); cnd_init(cqueue->cqcnd); - cqueue->cstatus = 0; - cqueue->len = QUEUE_LEN; - cqueue->used = 0; - cqueue->queue = xcalloc(cqueue->len, sizeof(struct thing *)); - - thrd_t *thread = xcalloc(1, sizeof(*thread)); - thrd_create(thread, consumer, (void *)cqueue); - - mtx_lock(cqueue->cqmutex); - cqueue->queue[cqueue->used] = xcalloc(1, sizeof(struct thing)); - cqueue->queue[cqueue->used]->cb = testcb; - cqueue->queue[cqueue->used]->arg = "This is some data"; - cqueue->used++; - mtx_unlock(cqueue->cqmutex); - cnd_signal(cqueue->cqcnd); - - sleep(1); +void stack_free(stack *st) { + if(!st) + return; + + for(int i = 0; i < st->used; i++) + gdata_free(st->arr[i]); + free(st->arr); + free(st); - mtx_lock(cqueue->cqmutex); - cqueue->cstatus++; - mtx_unlock(cqueue->cqmutex); - cnd_broadcast(cqueue->cqcnd); + return; +} - // Destroy and free everything - mtx_destroy(cqueue->cqmutex); cnd_destroy(cqueue->cqcnd); - free(cqueue->cqmutex); free(cqueue->cqcnd); - free(cqueue->queue); - free(cqueue); +int stack_push(stack *st, gdata *data) { + if(!st || !data) + return -1; + if(st->used == st->size) + return 0; - return 0; + st->arr[st->used++] = data; + + return st->used; +} + +int stack_pushd(stack *st, void *data, fcallback fcb) { + return stack_push(st, gdata_init(data, fcb)); +} + +gdata * stack_pop(stack *st) { + if(!st) + return NULL; + if(st->used <= 0) + return NULL; + + gdata *gd = st->arr[--st->used]; + return gd; } -// Ok well now I'm pissed. The canceling works fine but it's not actually consuming the thing \ No newline at end of file +void * stack_popd(stack *st) { + gdata *gd = stack_pop(st); + void *data = NULL; + + gdata_destruct(gd, &data); + return data; +} + + + +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); + + + return 0; +} \ No newline at end of file diff --git a/src/~Makefile b/src/~Makefile new file mode 100644 index 0000000..b045807 --- /dev/null +++ b/src/~Makefile @@ -0,0 +1,39 @@ +CC = gcc +SHELL := /usr/bin/env +.SHELLFLAGS := -S bash -c + +# I need to get better at makefiles so I can write this in a way that isn't absolutely insane/stupid +# RELEASE_CFLAGS := -O3 -fipa-pta -fipa-cp -fuse-linker-plugin -flto=auto +# RELEASE_LDFLAGS := -fuse-linker-plugin -flto=auto + +CFLAGS = -std=c2x -Wall -Wextra -Wpedantic -pedantic-errors -fanalyzer -Wanalyzer-too-complex -ggdb -g3 -O0 $$(pkg-config --cflags libsodium) +LDLIBS += $$(pkg-config --libs-only-l libsodium) +LDFLAGS += $$(pkg-config --libs-only-L libsodium) +DEPFLAGS = -MT $@ -MMD -MP -MF $*.d + +SOURCES := $(wildcard *.c) +OBJECTS := $(patsubst %.c,%.o,$(SOURCES)) +DEPS := $(patsubst %.c,%.d,$(SOURCES)) + +COMPILE.c = $(CC) $(DEPFLAGS) $(CFLAGS) -c + +.PHONY: all c clean val +.DELETE_ON_ERROR: +.ONESHELL: + +all: main +main: $(OBJECTS) + +%.o: %.c %.d + $(COMPILE.c) $< + +$(DEPS): +include $(wildcard $(DEPS)) +# Adopted from https://make.mad-scientist.net/papers/advanced-auto-dependency-generation/ + +c clean: + @-rm -rv main $(OBJECTS) $(DEPS) $(wildcard *.test*) $(wildcard *.enc) + +val: + $(MAKE) all + valgrind --leak-check=yes ./main \ No newline at end of file -- cgit v1.2.3