aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2023-02-18 01:00:46 +0100
committerMarvin Borner2023-02-18 01:00:46 +0100
commitbe5d819c903540419d162afda7fb16e8960233cc (patch)
tree3370749c14acb9b4e030aeb8048cc152706bfe90
parentec5b8ff7352984f8b63b79995df15527bd7a9e70 (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.h1
-rw-r--r--makefile10
-rw-r--r--src/main.c20
-rw-r--r--src/reducer.c36
-rw-r--r--src/store.c21
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
diff --git a/makefile b/makefile
index 144fa09..586949d 100644
--- a/makefile
+++ b/makefile
@@ -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
diff --git a/src/main.c b/src/main.c
index 9844828..f28d6cc 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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;