diff options
| author | iamcheeseman <[email protected]> | 2026-05-10 00:28:14 -0400 |
|---|---|---|
| committer | iamcheeseman <[email protected]> | 2026-05-10 00:28:14 -0400 |
| commit | 576bd27e11ec70bdbd1b9a644d2e227b57586337 (patch) | |
| tree | 2dc41e3f88bb95568f73ee372fc35512afcbcf9b /teensy/teensy_mem.c | |
| parent | 9ed5698b3c74c7ce1784d3bebe2aa73d5a0c319d (diff) | |
i ain't splitting alla this up
Diffstat (limited to 'teensy/teensy_mem.c')
| -rw-r--r-- | teensy/teensy_mem.c | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/teensy/teensy_mem.c b/teensy/teensy_mem.c new file mode 100644 index 0000000..2a6d992 --- /dev/null +++ b/teensy/teensy_mem.c @@ -0,0 +1,171 @@ +#include "teensy_mem.h" + +#include "teensy_common.h" +#include "teensy_list.h" + +// Array to track temp allocations. +void **temp_allocations; + +#ifdef TEENSY_DEBUG + +#include <execinfo.h> + +#define BACKTRACE_SIZE 16 + +struct alloc { + void *ptr; + size_t size; + int backtrace_len; + char **backtrace; +}; + +int allocations_cap; +int allocations_len; +struct alloc *allocations; + +#endif // TODO TEENSY_DEBUG + +void ty_init_mem(void) +{ +#ifdef TEENSY_DEBUG + allocations_len = 0; + allocations_cap = 8; + allocations = malloc(sizeof(struct alloc) * 8); + if (!allocations) + ty_log_fatal(TY_ERR_MEM, "(%s) (track) ran out of memory", __func__); +#endif // TEENSY_DEBUG + + temp_allocations = ty_list_create(); +} + +void ty_deinit_mem(void) +{ + ty_list_free(temp_allocations); +#ifdef TEENSY_DEBUG + fprintf(stderr, "%d allocations leaked\n", allocations_len); + for (int i = 0; i < allocations_len; i++) { + struct alloc *alloc = &allocations[i]; + fprintf( + stderr, + "leaked %zu bytes at %p\n", + alloc->size, + alloc->ptr + ); + for (int j = 0; j < alloc->backtrace_len; j++) { + fprintf(stderr, "\t%s\n", alloc->backtrace[j]); + } + putc('\n', stderr); + + free(alloc->backtrace); + } + free(allocations); + + if (allocations_len > 0) + exit(TY_ERR_MEM_LEAK); +#endif // TEENSY_DEBUG +} + +void ty_free_temp_allocs(void) +{ + for (size_t i = 0; i < ty_list_len(temp_allocations); i++) { + void *temp = temp_allocations[i]; + ty_free(temp); + } + ty_list_clear(temp_allocations); +} + +void *ty_alloc(size_t size) +{ + void *ptr = malloc(size); + if (!ptr) + ty_log_fatal(TY_ERR_MEM, "(%s) ran out of memory", __func__); + +#ifdef TEENSY_DEBUG + // Log allocation + struct alloc alloc; + void *bt[BACKTRACE_SIZE]; + int bt_len = backtrace(bt, BACKTRACE_SIZE); + char **symbols = backtrace_symbols(bt, bt_len); + + alloc.ptr = ptr; + alloc.size = size; + alloc.backtrace_len = bt_len; + alloc.backtrace = symbols; + + if (allocations_len + 1 > allocations_cap) { + allocations_cap *= 2; + allocations = realloc( + allocations, + sizeof(struct alloc) * allocations_cap + ); + if (!allocations) + ty_log_fatal( + TY_ERR_MEM, + "(%s) (track) ran out of memory", + __func__ + ); + } + + allocations[allocations_len++] = alloc; +#endif // TEENSY_DEBUG + + return ptr; +} + +void *ty_realloc(void *ptr, size_t new_size) +{ + if (new_size == 0) { + ty_free(ptr); + return NULL; + } + + void *new_ptr = realloc(ptr, new_size); + if (!new_ptr) + ty_log_fatal(TY_ERR_MEM, "(%s) ran out of memory", __func__); + +#ifdef TEENSY_DEBUG + for (int i = 0; i < allocations_len; i++) { + struct alloc *alloc = &allocations[i]; + if (alloc->ptr == ptr) { + alloc->ptr = new_ptr; + alloc->size = new_size; + break; + } + } +#endif // TEENSY_DEBUG + + return new_ptr; +} + +void *ty_talloc(size_t size) +{ + void *ptr = ty_alloc(size); + ty_list_append(temp_allocations, ptr); + return ptr; +} + +void ty_free(void *ptr) +{ + free(ptr); + +#ifdef TEENSY_DEBUG + for (int i = 0; i < allocations_len; i++) { + struct alloc *alloc = &allocations[i]; + if (alloc->ptr == ptr) { + free(alloc->backtrace); + *alloc = allocations[allocations_len - 1]; + allocations_len--; + break; + } + } +#endif // TEENSY_DEBUG +} + +int ty_alloc_count(void) +{ +#ifdef TEENSY_DEBUG + return allocations_len; +#else + return -1; +#endif +} |
