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
|
#pragma once
#include <stddef.h>
#include <stdbool.h>
#ifndef TB_API
# ifdef __cplusplus
# define TB_EXTERN extern "C"
# else
# define TB_EXTERN
# endif
# ifdef TB_DLL
# ifdef TB_IMPORT_DLL
# define TB_API TB_EXTERN __declspec(dllimport)
# else
# define TB_API TB_EXTERN __declspec(dllexport)
# endif
# else
# define TB_API TB_EXTERN
# endif
#endif
enum {
TB_ARENA_SMALL_CHUNK_SIZE = 4 * 1024,
TB_ARENA_MEDIUM_CHUNK_SIZE = 512 * 1024,
TB_ARENA_LARGE_CHUNK_SIZE = 16 * 1024 * 1024,
TB_ARENA_ALIGNMENT = 16,
};
typedef struct TB_ArenaChunk TB_ArenaChunk;
struct TB_ArenaChunk {
TB_ArenaChunk* next;
size_t pad;
char data[];
};
typedef struct TB_Arena {
size_t chunk_size;
TB_ArenaChunk* base;
TB_ArenaChunk* top;
// top of the allocation space
char* watermark;
char* high_point; // &top->data[chunk_size]
} TB_Arena;
typedef struct TB_ArenaSavepoint {
TB_ArenaChunk* top;
char* watermark;
} TB_ArenaSavepoint;
#define TB_ARENA_FOR(it, arena) for (TB_ArenaChunk* it = (arena)->base; it != NULL; it = it->next)
#define TB_ARENA_ALLOC(arena, T) tb_arena_alloc(arena, sizeof(T))
#define TB_ARENA_ARR_ALLOC(arena, count, T) tb_arena_alloc(arena, (count) * sizeof(T))
TB_API void tb_arena_create(TB_Arena* restrict arena, size_t chunk_size);
TB_API void tb_arena_destroy(TB_Arena* restrict arena);
TB_API void* tb_arena_unaligned_alloc(TB_Arena* restrict arena, size_t size);
TB_API void* tb_arena_alloc(TB_Arena* restrict arena, size_t size);
// return false on failure
TB_API bool tb_arena_free(TB_Arena* restrict arena, void* ptr, size_t size);
TB_API void tb_arena_pop(TB_Arena* restrict arena, void* ptr, size_t size);
// in case you wanna mix unaligned and aligned arenas
TB_API void tb_arena_realign(TB_Arena* restrict arena);
TB_API bool tb_arena_is_empty(TB_Arena* arena);
TB_API size_t tb_arena_current_size(TB_Arena* arena);
// savepoints
TB_API TB_ArenaSavepoint tb_arena_save(TB_Arena* arena);
TB_API void tb_arena_restore(TB_Arena* arena, TB_ArenaSavepoint sp);
// resets to only having one chunk
TB_API void tb_arena_clear(TB_Arena* arena);
|