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.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/memstack/src/memstack.c b/memstack/src/memstack.c
index 10d1e30..0848afb 100644
--- a/memstack/src/memstack.c
+++ b/memstack/src/memstack.c
@@ -5,6 +5,16 @@
5#include <stdlib.h> 5#include <stdlib.h>
6#include <string.h> 6#include <string.h>
7 7
8static bool is_pow2_or_0(size_t x) { return (x & (x - 1)) == 0; }
9
10/// Align the given address to the next address that is a multiple of the
11/// alignment. If the given address is already aligned, return the address.
12static uint8_t* align(uint8_t* address, size_t alignment) {
13 assert(is_pow2_or_0(alignment));
14 const size_t mask = alignment - 1;
15 return (uint8_t*)(((uintptr_t)address + mask) & ~mask);
16}
17
8bool memstack_make(memstack* stack, size_t capacity, void* memory) { 18bool memstack_make(memstack* stack, size_t capacity, void* memory) {
9 assert(stack); 19 assert(stack);
10 assert(capacity >= 1); 20 assert(capacity >= 1);
@@ -59,13 +69,24 @@ void* memstack_alloc(memstack* stack, size_t bytes) {
59 } 69 }
60 70
61 // Allocate the block. 71 // Allocate the block.
62 uint8_t* block = stack->watermark; 72 uint8_t* const block = stack->watermark;
63 stack->watermark += bytes; 73 stack->watermark += bytes;
64 assert(memstack_size(stack) <= stack->capacity); 74 assert(memstack_size(stack) <= stack->capacity);
65 75
66 return block; 76 return block;
67} 77}
68 78
79void* memstack_alloc_aligned(memstack* stack, size_t bytes, size_t alignment) {
80 assert(stack);
81
82 uint8_t* const new_watermark = align(stack->watermark, alignment);
83 assert(new_watermark >= stack->watermark);
84 assert((size_t)(new_watermark - stack->base) <= stack->capacity);
85 stack->watermark = new_watermark;
86
87 return memstack_alloc(stack, bytes);
88}
89
69size_t memstack_size(const memstack* stack) { 90size_t memstack_size(const memstack* stack) {
70 assert(stack); 91 assert(stack);
71 return stack->watermark - stack->base; 92 return stack->watermark - stack->base;