diff options
-rw-r--r-- | memstack/include/memstack.h | 6 | ||||
-rw-r--r-- | memstack/src/memstack.c | 16 | ||||
-rw-r--r-- | memstack/test/memstack_test.c | 31 |
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. |
33 | void memstack_clear(memstack*); | 33 | void memstack_clear(memstack*); |
34 | 34 | ||
35 | /// Return the top of the stack. | ||
36 | size_t memstack_watermark(const memstack*); | ||
37 | |||
38 | /// Set the top of the stack. | ||
39 | void 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 | ||
61 | size_t memstack_watermark(const memstack* stack) { | ||
62 | assert(stack); | ||
63 | return stack->watermark - stack->base; | ||
64 | } | ||
65 | |||
66 | void 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 | |||
61 | void* memstack_alloc(memstack* stack, size_t bytes) { | 76 | void* 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. | ||
135 | TEST_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 | |||
134 | int main() { return 0; } | 165 | int main() { return 0; } |