summaryrefslogtreecommitdiff
path: root/src/arena.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/arena.c')
-rw-r--r--src/arena.c143
1 files changed, 0 insertions, 143 deletions
diff --git a/src/arena.c b/src/arena.c
deleted file mode 100644
index 8f32064..0000000
--- a/src/arena.c
+++ /dev/null
@@ -1,143 +0,0 @@
1#include "arena.h"
2#include "shared.h"
3
4#include <asm-generic/errno-base.h>
5#include <stddef.h>
6#include <stdint.h>
7#include <stdlib.h>
8#include <errno.h>
9#include <error.h>
10
11typedef struct an {
12 void *membase;
13 void *memcur;
14 size_t allocated;
15 size_t used;
16
17 struct an *next;
18} arenanode;
19
20typedef struct arena {
21 arenanode *start;
22 arenanode *current;
23
24 // For keeping track of the largest possible thing that can be allocated to one node
25 // I don't know if I care to keep this or remove it. I'll see if it becomes a problem / is useful
26 size_t node_memspace;
27} arena;
28
29arenanode * arenanode_init(size_t bytes) {
30 if(bytes < 1) ERRRET(EINVAL, NULL);
31
32 arenanode *an = VALLOC(1, sizeof(*an));
33 if(!an)
34 return NULL;
35
36 an->allocated = bytes;
37 an->used = 0;
38 an->next = NULL;
39
40 void *mem = VALLOC(bytes, 1);
41 if(!mem) {
42 free(an);
43 return NULL;
44 }
45
46 an->membase = mem;
47 an->memcur = mem;
48
49 return an;
50}
51
52arena * arena_init(size_t bytes) {
53 if(!ISPOWOF2(MEM_ALIGN_BYTES)) XALLOC_EXIT("<arena_init> \"MEM_ALIGN_BYTES\" is not a power of 2. Refusing to create a new arena", );
54 if(bytes < 1) ERRRET(EINVAL, NULL);
55
56 arena *a = VALLOC(1, sizeof(arena));
57 if(!a)
58 return NULL;
59
60 a->start = NULL;
61 a->current = NULL;
62 a->node_memspace = bytes;
63
64 arenanode *base = arenanode_init(bytes);
65 if(!base) {
66 free(a);
67 return NULL;
68 }
69
70 a->start = base;
71 a->current = base;
72
73 return a;
74}
75
76void * arena_alloc(arena * const arena, size_t bytes) {
77 if(!ISPOWOF2(MEM_ALIGN_BYTES)) XALLOC_EXIT("<arena_alloc> \"MEM_ALIGN_BYTES\" is not a power of 2. Refusing to allocate any memory", );
78 if(!arena) ERRRET(EINVAL, NULL);
79 if(bytes > arena->node_memspace) ERRRET(ENOMEM, NULL);
80
81 if(bytes > ((arena->current)->allocated - (arena->current)->used)) {
82 arenanode *new = arenanode_init(arena->node_memspace);
83 if(!new)
84 return NULL;
85
86 arena->current->next = new;
87 arena->current = new;
88 }
89
90 size_t alignment = MEM_ALIGN(bytes);
91 size_t offset = bytes + alignment;
92
93 void *mem = arena->current->memcur;
94 arena->current->memcur = (void*)(((uint8_t*)arena->current->memcur) + offset);
95
96 arena->current->used += offset;
97
98 return mem;
99
100 // Note: This implementation assumes that malloc provides already-aligned memory. If it
101 // doesn't, that sucks and blows everything up
102}
103
104void arena_free(void *a) {
105 if(!a)
106 return;
107
108 arena *real = (arena *)a;
109 real->current = real->start;
110 for(arenanode *n; real->current != NULL;) {
111 n = real->current->next;
112
113 free(real->current->membase);
114 free(real->current);
115
116 real->current = n;
117 }
118 free(real);
119
120 return;
121}
122
123
124
125
126simplearena * simplearena_init(size_t bytes) {
127 return arena_init(bytes);
128}
129
130void * simplearena_alloc(simplearena * const a, size_t bytes) {
131 // The criteria to allocate new memory in arena_alloc is 'bytes > ((a->current)->allocated - (a->current)->used)', so if this
132 // is true, just return NULL & set errno
133
134 if(!a) ERRRET(EINVAL, NULL);
135 if(bytes > ((a->current)->allocated - (a->current)->used)) ERRRET(ENOMEM, NULL);
136
137 return arena_alloc(a, bytes);
138}
139
140void simplearena_free(simplearena *a) {
141 arena_free(a);
142 return;
143} \ No newline at end of file