From f99204184c8b96f499f6e7efbffb8b6b4ea8c93f Mon Sep 17 00:00:00 2001 From: 3gg <3gg@shellblade.net> Date: Tue, 1 Jul 2025 09:34:22 -0700 Subject: Add memstack --- memstack/src/memstack.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 memstack/src/memstack.c (limited to 'memstack/src/memstack.c') diff --git a/memstack/src/memstack.c b/memstack/src/memstack.c new file mode 100644 index 0000000..10d1e30 --- /dev/null +++ b/memstack/src/memstack.c @@ -0,0 +1,82 @@ +#include "memstack.h" + +#include + +#include +#include + +bool memstack_make(memstack* stack, size_t capacity, void* memory) { + assert(stack); + assert(capacity >= 1); + + // Allocate memory if not user-provided. + uint8_t* stack_memory = memory; + if (!stack_memory) { + stack_memory = calloc(1, capacity); + if (stack_memory == nullptr) { + return false; + } + } + assert(stack_memory); + + stack->capacity = capacity; + stack->base = stack_memory; + stack->watermark = stack_memory; + stack->owned = (stack_memory != memory); + stack->trap = true; + + return true; +} + +void memstack_del(memstack* stack) { + assert(stack); + + if (stack->owned && (stack->base != nullptr)) { + free(stack->base); + stack->base = nullptr; + stack->owned = false; + } + + stack->capacity = 0; + stack->watermark = stack->base; +} + +void memstack_clear(memstack* stack) { + assert(stack); + + stack->watermark = stack->base; + memset(stack->base, 0, stack->capacity); +} + +void* memstack_alloc(memstack* stack, size_t bytes) { + assert(stack); + + if ((memstack_size(stack) + bytes) > stack->capacity) { + if (stack->trap) { + FAIL("memstack allocation failed, increase the stack's capacity."); + } + return nullptr; // Block does not fit in remaining memory. + } + + // Allocate the block. + uint8_t* block = stack->watermark; + stack->watermark += bytes; + assert(memstack_size(stack) <= stack->capacity); + + return block; +} + +size_t memstack_size(const memstack* stack) { + assert(stack); + return stack->watermark - stack->base; +} + +size_t memstack_capacity(const memstack* stack) { + assert(stack); + return stack->capacity; +} + +void memstack_enable_traps(memstack* stack, bool enable) { + assert(stack); + stack->trap = enable; +} -- cgit v1.2.3