aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-07-19 09:43:50 -0700
committer3gg <3gg@shellblade.net>2025-07-19 09:43:50 -0700
commitb905c803f35ee41ed894a108cc8fa114a2a58b88 (patch)
treef67bb65087208fa85b30011a07e8e23bd8e7ef9a
parent75705ca3d91930a730743b5319268087fc7bc56e (diff)
Add functions to get and set the watermarkHEADmain
-rw-r--r--memstack/include/memstack.h6
-rw-r--r--memstack/src/memstack.c16
-rw-r--r--memstack/test/memstack_test.c31
3 files changed, 53 insertions, 0 deletions
diff --git a/memstack/include/memstack.h b/memstack/include/memstack.h
index 97a9d12..93cd2e6 100644
--- a/memstack/include/memstack.h
+++ b/memstack/include/memstack.h
@@ -32,6 +32,12 @@ void memstack_del(memstack*);
32/// Clear the stack. 32/// Clear the stack.
33void memstack_clear(memstack*); 33void memstack_clear(memstack*);
34 34
35/// Return the top of the stack.
36size_t memstack_watermark(const memstack*);
37
38/// Set the top of the stack.
39void memstack_set_watermark(memstack*, size_t watermark);
40
35/// Allocate a new block. 41/// Allocate a new block.
36/// 42///
37/// Return null if the block does not fit in the remaining memory. 43/// Return null if the block does not fit in the remaining memory.
diff --git a/memstack/src/memstack.c b/memstack/src/memstack.c
index 0848afb..84131ef 100644
--- a/memstack/src/memstack.c
+++ b/memstack/src/memstack.c
@@ -58,6 +58,21 @@ void memstack_clear(memstack* stack) {
58 memset(stack->base, 0, stack->capacity); 58 memset(stack->base, 0, stack->capacity);
59} 59}
60 60
61size_t memstack_watermark(const memstack* stack) {
62 assert(stack);
63 return stack->watermark - stack->base;
64}
65
66void memstack_set_watermark(memstack* stack, size_t watermark) {
67 assert(stack);
68 const bool fits = (watermark < stack->capacity);
69 if (stack->trap && !fits) {
70 FAIL("memstack watermark update failed, bad watermark");
71 }
72 assert(fits);
73 stack->watermark = stack->base + watermark;
74}
75
61void* memstack_alloc(memstack* stack, size_t bytes) { 76void* memstack_alloc(memstack* stack, size_t bytes) {
62 assert(stack); 77 assert(stack);
63 78
@@ -82,6 +97,7 @@ void* memstack_alloc_aligned(memstack* stack, size_t bytes, size_t alignment) {
82 uint8_t* const new_watermark = align(stack->watermark, alignment); 97 uint8_t* const new_watermark = align(stack->watermark, alignment);
83 assert(new_watermark >= stack->watermark); 98 assert(new_watermark >= stack->watermark);
84 assert((size_t)(new_watermark - stack->base) <= stack->capacity); 99 assert((size_t)(new_watermark - stack->base) <= stack->capacity);
100 stack->capacity -= (new_watermark - stack->watermark);
85 stack->watermark = new_watermark; 101 stack->watermark = new_watermark;
86 102
87 return memstack_alloc(stack, bytes); 103 return memstack_alloc(stack, bytes);
diff --git a/memstack/test/memstack_test.c b/memstack/test/memstack_test.c
index 285cf46..5308be3 100644
--- a/memstack/test/memstack_test.c
+++ b/memstack/test/memstack_test.c
@@ -131,4 +131,35 @@ TEST_CASE(memstack_alloc_aligned) {
131 memstack_del(&stack); 131 memstack_del(&stack);
132} 132}
133 133
134// Get and set the watermark.
135TEST_CASE(memstack_watermark) {
136 memstack stack = {0};
137 memstack_make(&stack, CAPACITY, nullptr);
138
139 // Allocate N/2 ints.
140 for (int i = 0; i < NUM_INTS / 2; ++i) {
141 const int* block = memstack_alloc(&stack, sizeof(int));
142 TEST_TRUE(block != nullptr);
143 }
144
145 const size_t watermark = memstack_watermark(&stack);
146
147 // Allocate the remaining N/2 ints.
148 for (int i = 0; i < NUM_INTS / 2; ++i) {
149 const int* block = memstack_alloc(&stack, sizeof(int));
150 TEST_TRUE(block != nullptr);
151 }
152
153 // Now reset the watermark halfway through.
154 memstack_set_watermark(&stack, watermark);
155
156 // Allocate the remaining N/2 ints (again).
157 for (int i = 0; i < NUM_INTS / 2; ++i) {
158 const int* block = memstack_alloc(&stack, sizeof(int));
159 TEST_TRUE(block != nullptr);
160 }
161
162 memstack_del(&stack);
163}
164
134int main() { return 0; } 165int main() { return 0; }