-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdlb_arena.h
66 lines (55 loc) · 2.11 KB
/
dlb_arena.h
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
#ifndef DLB_ARENA_H
#define DLB_ARENA_H
//------------------------------------------------------------------------------
// Copyright 2018 Dan Bechard
//------------------------------------------------------------------------------
//-- header --------------------------------------------------------------------
#include "dlb_memory.h"
#include "dlb_vector.h"
typedef struct dlb_arena {
char *ptr; // Next free
char *end; // End of current block
char **blocks; // Linked list of allocated blocks
} dlb_arena;
#define DLB_ARENA_ALIGNMENT 8
#define DLB_ARENA_BLOCK_SIZE 1024
void dlb_arena__grow(dlb_arena *arena, size_t min_size);
void *dlb_arena_alloc(dlb_arena *arena, size_t size);
void dlb_arena_free(dlb_arena *arena);
#endif
//-- end of header -------------------------------------------------------------
#ifdef __INTELLISENSE__
/* This makes MSVC intellisense work. */
#define DLB_ARENA_IMPLEMENTATION
#endif
//-- implementation ------------------------------------------------------------
#ifdef DLB_ARENA_IMPLEMENTATION
#ifndef DLB_ARENA_IMPL_INTERNAL
#define DLB_ARENA_IMPL_INTERNAL
void dlb_arena__grow(dlb_arena *arena, size_t min_size) {
size_t size = ALIGN_UP(MAX(DLB_ARENA_BLOCK_SIZE, min_size),
DLB_ARENA_ALIGNMENT);
arena->ptr = dlb_malloc(size);
arena->end = arena->ptr + size;
dlb_vec_push(arena->blocks, arena->ptr);
}
void *dlb_arena_alloc(dlb_arena *arena, size_t size) {
// If current block isn't big enough, stop using it and allocate a new one
if (size > (size_t)(arena->end - arena->ptr)) {
dlb_arena__grow(arena, size);
assert(size <= (size_t)(arena->end - arena->ptr));
}
void *ptr = arena->ptr;
arena->ptr = ALIGN_UP_PTR(arena->ptr + size, DLB_ARENA_ALIGNMENT);
assert(arena->ptr <= arena->end);
assert(ptr == ALIGN_DOWN_PTR(ptr, DLB_ARENA_ALIGNMENT));
return ptr;
}
void dlb_arena_free(dlb_arena *arena) {
for (char **it = arena->blocks; it != dlb_vec_end(arena->blocks); it++) {
free(*it);
}
}
#endif
#endif
//-- end of implementation -----------------------------------------------------