blob: 3e1a57c641242a30c7e8fb1e2c8857a73466787a (
plain) (
blame)
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
|
#include "arena.h"
#include <stdlib.h>
#define PAGE_SIZE 4096
enum {
ARENA_SUCCESS = 0,
ARENA_EXPAND,
ARENA_FAILURE,
}
int arena_errno;
arena_t* arena_create_sized(size_t size){
arena_t* arena = (arena_t*) calloc(1, sizeof(arena_t*));
if (!arena) {
arena_errno = ARENA_FAILURE;
return 0;
}
arena->memory = (uint8_t*) calloc(1, size);
arena->size = size;
if (!arena->memory) {
free(arena);
arena_errno = ARENA_FAILURE;
return 0;
}
arena_errno = ARENA_SUCCESS;
return arena;
}
arena_t* arena_create() {
return arena_create_sized(PAGE_SIZE);
}
void* arena_malloc(arena_t* arena, size_t size) {
arena_t* head = arena;
arena_t* tail;
do {
if ((arena->size - arena->fill) > size) {
arena->fill += size;
// NOTE: do not overwrite ARENA_EXPAND code
if (arena_errno != ARENA_EXPAND) arena_errno = ARENA_SUCCESS;
return arena->memory + (arena->fill - size);
}
} while ((arena = arena->next) != 0);
tail = arena_create();
if (tail == 0) {
// NOTE: `arena_errno` is already set from `arena_create`
return 0;
}
arena_errno = ARENA_EXPAND;
return arena_malloc(tail, size);
}
void arena_destroy(arena_t* arena) {
arena_t* tail = arena;
do {
free(tail->memory);
free(tail);
tail = tail->next;
} while (tail != 0);
arena_errno = ARENA_SUCCESS;
}
|