summaryrefslogtreecommitdiff
path: root/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'base.c')
-rw-r--r--base.c172
1 files changed, 172 insertions, 0 deletions
diff --git a/base.c b/base.c
new file mode 100644
index 0000000..519e644
--- /dev/null
+++ b/base.c
@@ -0,0 +1,172 @@
1#include <sys/mman.h>
2#include <stddef.h>
3#include <stdint.h>
4#include <string.h>
5#include <assert.h>
6
7#define OK 0
8#define ERR_IO 1
9#define ERR_PARSE 2
10#define ERR_PERM 3
11#define ERR_INVALID 4
12
13enum
14{
15 BUFFER_SIZE_SMALL = 128,
16 BUFFER_SIZE_DEFAULT = 256,
17 BUFFER_SIZE_LARGE = 512,
18 PATH_MAX_LEN = 4096
19};
20
21typedef uint64_t u64;
22typedef uint32_t u32;
23typedef uint16_t u16;
24typedef uint8_t u8;
25
26typedef int8_t i8;
27typedef int16_t i16;
28typedef int32_t i32;
29typedef int64_t i64;
30
31typedef i16 b16;
32typedef i32 b32;
33
34static inline u64
35KiB(u64 n)
36{
37 return n << 10;
38}
39static inline u64
40MiB(u64 n)
41{
42 return n << 20;
43}
44static inline u64
45GiB(u64 n)
46{
47 return n << 30;
48}
49
50typedef struct mem_arena mem_arena;
51mem_arena *
52arena_create(u64 capacity);
53void
54arena_destroy(mem_arena *arena);
55void
56arena_clear(mem_arena *arena);
57
58/**
59 * Arena Helper macro's
60 * */
61
62#define MIN(a, b) (((a) < (b)) ? (a) : (b))
63#define MAX(a, b) (((a) > (b)) ? (a) : (b))
64#define ALIGN_UP_POW2(n, p) (((u64)(n) + ((u64)(p) - 1)) & (~((u64)(p) - 1)))
65
66/*
67 * Represents a disk partition with major/minor device numbers and block count.
68 */
69
70/**
71 * replacing malloc/free with arena allocaters
72 *
73 * */
74
75#define ARENA_BASE_POS (sizeof(mem_arena))
76// void * for the size of a pointer on the machine, 64/32bit comp
77#define ARENA_ALIGN (sizeof(void *))
78
79struct mem_arena
80{
81 u64 capacity;
82 u64 pos;
83};
84
85// arena prototypes
86mem_arena *
87arena_create(u64 capacity);
88// make it a void pointer to allow implicit conversion
89void
90arena_destroy(mem_arena *arena);
91
92void *
93arena_push(mem_arena *arena, u64 size, b32 non_zero);
94
95void
96arena_pop(mem_arena *arena, u64 size);
97
98void
99arena_pop_to(mem_arena *arena, u64 pos);
100
101void
102arena_clear(mem_arena *arena);
103
104mem_arena *
105arena_create(u64 capacity)
106{
107 mem_arena *arena = mmap(0, capacity, PROT_READ | PROT_WRITE | PROT_EXEC,
108 MAP_SHARED | MAP_ANONYMOUS, -1, 0);
109 if (arena == MAP_FAILED)
110 {
111 assert(0);
112 }
113
114 arena->capacity = capacity;
115 arena->pos = ARENA_BASE_POS;
116
117 return arena;
118}
119
120// make it a void pointer to allow implicit conversion
121void
122arena_destroy(mem_arena *arena)
123{
124 munmap(arena, arena->capacity);
125}
126
127void *
128arena_push(mem_arena *arena, u64 size, b32 non_zero)
129{
130 u64 pos_aligned = ALIGN_UP_POW2(arena->pos, ARENA_ALIGN);
131 u64 new_pos = pos_aligned + size;
132
133 if (new_pos > arena->capacity)
134 {
135 assert(0);
136 return NULL;
137 }
138
139 arena->pos = new_pos;
140 // cast to u8 to be able to do pointer arithemtic
141 u8 *out = (u8 *)arena + pos_aligned;
142
143 if (!non_zero)
144 {
145 memset(out, 0, size);
146 }
147 return out;
148}
149void
150arena_pop(mem_arena *arena, u64 size)
151{
152 size = MIN(size, arena->pos - ARENA_BASE_POS);
153 arena->pos -= size;
154}
155
156void
157arena_pop_to(mem_arena *arena, u64 pos)
158{
159 u64 size = pos < arena->pos ? arena->pos - pos : 0;
160 arena_pop(arena, size);
161}
162
163void
164arena_clear(mem_arena *arena)
165{
166 arena_pop_to(arena, ARENA_BASE_POS);
167}
168
169#define PUSH_STRUCT(arena, T) (T *)arena_push((arena), sizeof(T), 0)
170#define PUSH_STRUCT_NZ(arena, T) (T *)arena_push((arena), sizeof(T), 1)
171#define PUSH_ARRAY(arena, T, n) (T *)arena_push((arena), sizeof(T) * (n), 0)
172#define PUSH_ARRAY_NZ(arena, T, n) (T *)arena_push((arena), sizeof(T) * (n), 1)