aboutsummaryrefslogtreecommitdiff
path: root/memstack/src/memstack.c
diff options
context:
space:
mode:
Diffstat (limited to 'memstack/src/memstack.c')
-rw-r--r--memstack/src/memstack.c82
1 files changed, 82 insertions, 0 deletions
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 @@
1#include "memstack.h"
2
3#include <cassert.h>
4
5#include <stdlib.h>
6#include <string.h>
7
8bool memstack_make(memstack* stack, size_t capacity, void* memory) {
9 assert(stack);
10 assert(capacity >= 1);
11
12 // Allocate memory if not user-provided.
13 uint8_t* stack_memory = memory;
14 if (!stack_memory) {
15 stack_memory = calloc(1, capacity);
16 if (stack_memory == nullptr) {
17 return false;
18 }
19 }
20 assert(stack_memory);
21
22 stack->capacity = capacity;
23 stack->base = stack_memory;
24 stack->watermark = stack_memory;
25 stack->owned = (stack_memory != memory);
26 stack->trap = true;
27
28 return true;
29}
30
31void memstack_del(memstack* stack) {
32 assert(stack);
33
34 if (stack->owned && (stack->base != nullptr)) {
35 free(stack->base);
36 stack->base = nullptr;
37 stack->owned = false;
38 }
39
40 stack->capacity = 0;
41 stack->watermark = stack->base;
42}
43
44void memstack_clear(memstack* stack) {
45 assert(stack);
46
47 stack->watermark = stack->base;
48 memset(stack->base, 0, stack->capacity);
49}
50
51void* memstack_alloc(memstack* stack, size_t bytes) {
52 assert(stack);
53
54 if ((memstack_size(stack) + bytes) > stack->capacity) {
55 if (stack->trap) {
56 FAIL("memstack allocation failed, increase the stack's capacity.");
57 }
58 return nullptr; // Block does not fit in remaining memory.
59 }
60
61 // Allocate the block.
62 uint8_t* block = stack->watermark;
63 stack->watermark += bytes;
64 assert(memstack_size(stack) <= stack->capacity);
65
66 return block;
67}
68
69size_t memstack_size(const memstack* stack) {
70 assert(stack);
71 return stack->watermark - stack->base;
72}
73
74size_t memstack_capacity(const memstack* stack) {
75 assert(stack);
76 return stack->capacity;
77}
78
79void memstack_enable_traps(memstack* stack, bool enable) {
80 assert(stack);
81 stack->trap = enable;
82}