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