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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
#ifndef ARENA_H
#define ARENA_H
#include "wrmr.h"
#include <stddef.h>
#include <stdint.h>
#include <string.h>
typedef struct {
char *start; /* need to release memory */
char *beg, *end;
} Arena;
#define ARENA(name, sz)\
static char name##_buf[sz];\
Arena name = { name##_buf, name##_buf + (sz) };
void *vmem_alloc(size_t sz);
void vmem_free(void *ptr, size_t sz);
Arena arena_init(size_t sz);
void arena_free(Arena *a);
void arena_reset(Arena *a);
void *arena_alloc(Arena *a, size_t n, size_t align);
void *arena_realloc(Arena *a, const void *old, size_t oldsz, size_t newsz, size_t align);
void *arena_concat(Arena *m, const void *a, size_t asz, const void *b, size_t bsz, size_t align);
#define new(a, t)\
memset(arena_alloc(a, sizeof(t), _Alignof(__typeof__(t))), 0, sizeof(t))
#define new_arr(a, t, n)\
memset(arena_alloc(a, sizeof(t) * (n), _Alignof(__typeof__(t))), 0, sizeof(t) * (n))
#define resize(a, x, osz, nsz)\
arena_realloc(a, x, sizeof(*(x)) * (osz),\
sizeof(*(x)) * (nsz), _Alignof(__typeof__(*(x))))
#ifdef ARENA_IMPL
/* virtual memory */
#include <stdio.h>
#include <sys/mman.h>
void *vmem_alloc(size_t sz) {
void *ptr = mmap(NULL, sz, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (!ptr) FAIL_WITH_MSG("mmap failed");
return ptr;
}
void vmem_free(void *ptr, size_t sz) {
munmap(ptr, sz);
}
/* arenas */
#include <string.h>
Arena arena_init(size_t sz) {
char *p = vmem_alloc(sz);
return (Arena) { p, p, p + sz };
}
void arena_free(Arena *a) {
vmem_free(a->start, a->end - a->start);
}
void arena_reset(Arena *a) {
a->beg = a->start;
}
#include <stdlib.h>
void *arena_alloc(Arena *a, size_t sz, size_t align) {
char *p = a->beg + (-(uintptr_t)a->beg & (align - 1));
if (p + sz > a->end) FAIL_WITH_MSG("arena out-of-memory");
a->beg = p + sz;
return p;
}
void *arena_realloc(Arena *a, const void *old, size_t oldsz, size_t newsz, size_t align) {
if (old == a->beg - oldsz) {
a->beg = (char*)old + newsz;
return (void*)old;
} else {
void *p = arena_alloc(a, newsz, align);
if (old) memcpy(p, old, oldsz);
return p;
}
}
void *arena_concat(Arena *m, const void *a, size_t asz, const void *b, size_t bsz, size_t align) {
if (!asz)
return (void*)b;
if (!bsz || (char*)a + asz == b)
return (void*)a;
void *p = arena_realloc(m, a, asz, asz + bsz, align);
memcpy((char*)p + asz, b, bsz);
return p;
}
#endif
#endif
|