diff options
author | Marvin Borner | 2023-02-18 01:00:46 +0100 |
---|---|---|
committer | Marvin Borner | 2023-02-18 01:00:46 +0100 |
commit | be5d819c903540419d162afda7fb16e8960233cc (patch) | |
tree | 3370749c14acb9b4e030aeb8048cc152706bfe90 | |
parent | ec5b8ff7352984f8b63b79995df15527bd7a9e70 (diff) |
Fixed more memory leaks
Doesn't seem to help much. I really need to sleep though so maybe i'm
just dumb
-rw-r--r-- | inc/store.h | 1 | ||||
-rw-r--r-- | makefile | 10 | ||||
-rw-r--r-- | src/main.c | 20 | ||||
-rw-r--r-- | src/reducer.c | 36 | ||||
-rw-r--r-- | src/store.c | 21 |
5 files changed, 66 insertions, 22 deletions
diff --git a/inc/store.h b/inc/store.h index a6df112..5e898a5 100644 --- a/inc/store.h +++ b/inc/store.h @@ -2,6 +2,7 @@ * MIT License * * Copyright (c) 2020 Samuel Vogelsanger <vogelsangersamuel@gmail.com> + * Copyright (c) 2023 Marvin Borner <dev@marvinborner.de> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -11,12 +11,16 @@ INC = $(PWD)/inc SRCS = $(wildcard $(SRC)/*.c) OBJS = $(patsubst $(SRC)/%.c, $(BUILD)/%.o, $(SRCS)) -CFLAGS_DEBUG = -Wno-error -g -Og -Wno-unused -fsanitize=address -fsanitize=undefined -fstack-protector-all $(CFLAGS_TEST) +CFLAGS_DEBUG = -Wno-error -g -O0 -Wno-unused -fsanitize=address -fsanitize=undefined CFLAGS_WARNINGS = -Wall -Wextra -Wshadow -Wpointer-arith -Wwrite-strings -Wredundant-decls -Wnested-externs -Wformat=2 -Wmissing-declarations -Wstrict-prototypes -Wmissing-prototypes -Wcast-qual -Wswitch-default -Wswitch-enum -Wunreachable-code -Wundef -Wold-style-definition -Wvla -pedantic -Wno-switch-enum -CFLAGS = $(CFLAGS_WARNINGS) -std=c99 -fno-profile-generate -fno-omit-frame-pointer -fno-common -fno-asynchronous-unwind-tables -mno-red-zone -Ofast -D_DEFAULT_SOURCE -I$(INC) #$(CFLAGS_DEBUG) +CFLAGS = $(CFLAGS_WARNINGS) -std=c99 -fno-omit-frame-pointer -Ofast -I$(INC) ifdef TEST # TODO: Somehow clean automagically -CFLAGS += -DTEST +CFLAGS += -DTEST -DNTESTS=$(TEST) +endif + +ifdef DEBUG # TODO: Somehow clean automagically +CFLAGS += $(CFLAGS_DEBUG) endif all: compile sync @@ -28,14 +28,17 @@ int main(void) return 0; } #else -#define TESTS 6 + +#ifndef NTESTS +#define NTESTS 6 +#endif + #define TESTDIR "./tests/" #include <stdlib.h> #include <string.h> #include <errno.h> #include <time.h> -#include <gc.h> static char *read_file(const char *path) { @@ -73,7 +76,7 @@ static struct { int alpha; int trans; } equivalency; -} tests[TESTS] = { 0 }; +} tests[NTESTS] = { 0 }; static int current = 0; static void callback(int i, char ch) @@ -82,7 +85,7 @@ static void callback(int i, char ch) fprintf(stderr, "Transition deviation at index %d!\n", i); tests[current].equivalency.trans = 0; } - /* printf("%d: %c\n", i, ch); */ + /* fprintf(stderr, "\n%d: %c\n", i, ch); */ } int main(void) @@ -91,7 +94,7 @@ int main(void) char red_template[] = TESTDIR "x.red"; char trans_template[] = TESTDIR "x.trans"; int offset = strlen(TESTDIR); - for (int i = 0; i < TESTS; i++) { + for (int i = 0; i < NTESTS; i++) { char ch = '0' + i + 1; in_template[offset] = ch; red_template[offset] = ch; @@ -111,17 +114,16 @@ int main(void) } clock_t begin = clock(); - for (current = 0; current < TESTS; current++) { + for (current = 0; current < NTESTS; current++) { tests[current].res = reduce(tests[current].in, callback); printf("Test %d done\n", current + 1); } clock_t end = clock(); - for (int i = 0; i < TESTS; i++) { + for (int i = 0; i < NTESTS; i++) { to_bruijn(tests[i].res); tests[i].equivalency.alpha = alpha_equivalency(tests[i].res, tests[i].red); - /* free(tests[i].in); */ free_term(tests[i].res); free_term(tests[i].red); } @@ -129,7 +131,7 @@ int main(void) printf("=== SUMMARY ===\n"); printf("Reduced tests in %.5fs\n", (double)(end - begin) / CLOCKS_PER_SEC); - for (int i = 0; i < TESTS; i++) { + for (int i = 0; i < NTESTS; i++) { if (tests[i].equivalency.alpha && tests[i].equivalency.trans) continue; printf("Test %d: [failed]\n\talpha-equivalency: %d\n\ttrans-equivalency: %d\n", diff --git a/src/reducer.c b/src/reducer.c index c5d8a89..0b5176c 100644 --- a/src/reducer.c +++ b/src/reducer.c @@ -74,19 +74,19 @@ static void release(void **ptr) struct tracked *tracked = *ptr; tracked->tracker--; if (tracked->tracker == 0) { - /* printf("Release %p (free)\n", tracked); */ + /* fprintf(stderr, "Release %p (free)\n", tracked); */ free(*ptr); } else { - /* printf("Release %p (%d)\n", tracked, tracked->tracker); */ + /* fprintf(stderr, "Release %p (%d)\n", tracked, tracked->tracker); */ } - /* *ptr = 0; // TODO: ? */ + /* *ptr = 0; // TODO: ? - nope, sry marvman */ } static void *acquire(void *ptr) { struct tracked *tracked = ptr; tracked->tracker++; - /* printf("Acquire %p (%d)\n", ptr, tracked->tracker); */ + /* fprintf(stderr, "Acquire %p (%d)\n", ptr, tracked->tracker); */ return ptr; } @@ -127,6 +127,7 @@ static void release_box(struct box **box) { release_term(&(*box)->term); release((void **)box); + *box = 0; } static void release_cache(struct cache **cache) @@ -136,12 +137,13 @@ static void release_cache(struct cache **cache) release((void **)cache); } -// expensive, only use when necessary +// TODO: probably goes way deeper than necessary (not that it really matters though) static struct term *acquire_term(struct term *term) { if (!term) // e.g. for empty boxes return term; + /* fprintf(stderr, "%d\n", term->type); */ acquire(term); switch (term->type) { case ABS: @@ -177,6 +179,20 @@ static struct box *acquire_box(struct box *box) return box; } +// TODO: Are these callbacks even necessary? Don't seem to make a big difference +void store_release_callback(void *store); +void store_release_callback(void *store) +{ + struct box *box = store; + release_box(&box); +} + +void store_acquire_callback(void *store); +void store_acquire_callback(void *store) +{ + acquire_box(store); +} + static struct stack *stack_push(struct stack *stack, void *data) { struct stack *new = acquire(track(malloc(sizeof(*new)))); @@ -259,7 +275,8 @@ static int transition_2(struct stack **stack, struct term **term, static int transition_3(struct term **term, struct store **store, struct stack **stack, struct box *box) { - struct term *orig = *term; + struct term *orig_term = *term; + struct store *orig_store = *store; assert(box->term->type == CLOSURE); struct closure *closure = box->term->u.other; @@ -276,8 +293,8 @@ static int transition_3(struct term **term, struct store **store, *store = store_acquire(closure->store); *stack = stack_push(*stack, cache_term); - release_term(&orig); - store_release(store); + release_term(&orig_term); + store_release(&orig_store); return 0; } @@ -299,8 +316,7 @@ static int transition_5(struct stack **stack, struct term **term, { cache->box->state = DONE; cache->box->term = *term; - /* acquire_term(*term); */ - acquire_box(cache->box); // TODO: ? + acquire_term(*term); *stack = stack_next(*stack); *term = acquire_term(*term); diff --git a/src/store.c b/src/store.c index 92d7099..784399a 100644 --- a/src/store.c +++ b/src/store.c @@ -2,6 +2,7 @@ * MIT License * * Copyright (c) 2020 Samuel Vogelsanger <vogelsangersamuel@gmail.com> + * Copyright (c) 2023 Marvin Borner <dev@marvinborner.de> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -247,11 +248,21 @@ static void iter_pop(struct store_iter *iterator); * definitions */ +extern void store_release_callback(void *data); + static void node_destroy(struct node *node) { DEBUG_NOTICE(" destroying " store_node_debug_fmt "@%p\n", store_node_debug_args(node), (void *)node); + // release boxes in node + if (node->ref_count == 0) { + for (unsigned i = 0; i < node->element_arity; ++i) { + struct kv kv = node->content[i]; + store_release_callback(kv.val); + } + } + // reference counting STORE_NODE_BRANCH_T *branches = (STORE_NODE_BRANCH_T *)STORE_NODE_BRANCHES(node); @@ -262,12 +273,21 @@ static void node_destroy(struct node *node) free(node); } +extern void store_acquire_callback(void *data); + // reference counting static inline struct node *store_node_acquire(const struct node *node) { if (node == &empty_node) return (struct node *)node; atomic_fetch_add((uint16_t *)&node->ref_count, 1u); + + // aqcuire boxes in node + for (unsigned i = 0; i < node->element_arity; ++i) { + struct kv kv = node->content[i]; + store_acquire_callback(kv.val); + } + return (struct node *)node; } @@ -898,6 +918,7 @@ static struct store *store_from(struct node *root, unsigned length, void store_destroy(struct store **store) { DEBUG_NOTICE("destroying store@%p\n", (void *)*store); + store_node_release((*store)->root); free(*store); *store = NULL; |