blob: 9a8a7ee7f41f9317e7768265c53d8f3d69ff4539 (
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
|
/*
* Stack-based allocator.
*/
#pragma once
#include <stddef.h>
#include <stdint.h>
/// Stack-based allocator.
typedef struct memstack {
size_t capacity; // Total size available.
uint8_t* base; // Base pointer to memory.
uint8_t* watermark; // Pointer to next free area of memory.
bool owned; // True if memory is owned by the memstack.
bool trap; // Whether to trap when allocating beyond capacity.
} memstack;
/// Create a stack-based allocator.
///
/// `stack` may be user-provided or null.
/// - If null, the allocator malloc()s the memory for them.
/// - If given, `stack` must be at least `capacity` bytes.
///
/// The memory is zeroed out for convenience.
bool memstack_make(memstack*, size_t capacity, void* memory);
/// Destroy the stack.
///
/// If the allocator owns the memory, then this function frees it.
void memstack_del(memstack*);
/// Clear the stack.
void memstack_clear(memstack*);
/// Allocate a new block.
/// Return null if the block does not fit in the remaining memory.
/// When there is no space left in the stack, allocation can either trap
/// (default) or gracefully return null. Call mem_enable_traps() to toggle this
/// behaviour.
/// Newly allocated blocks are conveniently zeroed out.
void* memstack_alloc(memstack*, size_t bytes);
/// Return the stack's used size in bytes.
size_t memstack_size(const memstack*);
/// Return the stack's total capacity in bytes.
size_t memstack_capacity(const memstack*);
/// Set whether to trap when attempting to allocate beyond capacity.
void memstack_enable_traps(memstack*, bool);
|