diff options
Diffstat (limited to 'memstack')
| -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; } |
