#include "teensy_mem.h" #include #include "teensy_common.h" #include "teensy_list.h" #define ARENA_DEFAULT_HUNK_SIZE (1<<16) // ~65KB Arena temp_arena; static Arena_Hunk *create_new_hunk(size_t hunk_size) { Arena_Hunk *hunk = ty_new(Arena_Hunk); memset(hunk, 0, sizeof(Arena_Hunk)); hunk->start = ty_alloc(hunk_size); hunk->end = hunk->start + hunk_size; hunk->head = hunk->start; return hunk; } void *ty_arena_alloc(Arena *arena, size_t size) { Arena_Hunk *hunk = arena->hunks; while (hunk) { if (hunk->head + size < hunk->end) break; hunk = hunk->next; } if (!hunk) { // I like these lines arena->hunk_size = arena->hunk_size ? arena->hunk_size : ARENA_DEFAULT_HUNK_SIZE; hunk = create_new_hunk(arena->hunk_size); hunk->next = arena->hunks; arena->hunks = hunk; } void *ptr = hunk->head; memset(ptr, 0, size); hunk->head += size; arena->alloced_size += size; return ptr; } void ty_arena_clear(Arena *arena) { Arena_Hunk *hunk = arena->hunks; while (hunk) { hunk->head = hunk->start; hunk = hunk->next; } arena->alloced_size = 0; } void ty_arena_free(Arena *arena) { Arena_Hunk *hunk = arena->hunks; while (hunk) { Arena_Hunk *next = hunk->next; ty_free(hunk->start); ty_free(hunk); hunk = next; } arena->hunks = NULL; arena->alloced_size = 0; } void *ty_talloc(size_t size) { return ty_arena_alloc(&temp_arena, size); } void ty_clear_temp_allocs(void) { ty_arena_clear(&temp_arena); } void *ty_alloc(size_t size) { if (size == 0) ty_log_fatal(TY_ERR_MEM, "(%s) tried to allocate 0 bytes", __func__); void *ptr = malloc(size); if (!ptr) ty_log_fatal(TY_ERR_MEM, "(%s) ran out of memory", __func__); return ptr; } void *ty_realloc(void *ptr, size_t new_size) { if (new_size == 0) { ty_free(ptr); return NULL; } // The pointer will not be registered in the tracker by realloc if it does // not yet exist. if (ptr == NULL) return ty_alloc(new_size); void *new_ptr = realloc(ptr, new_size); if (!new_ptr) ty_log_fatal(TY_ERR_MEM, "(%s) ran out of memory", __func__); return new_ptr; } void ty_free(void *ptr) { free(ptr); }