-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patharena_alloc.c
More file actions
80 lines (74 loc) · 1.85 KB
/
Copy patharena_alloc.c
File metadata and controls
80 lines (74 loc) · 1.85 KB
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
#define _POSIX_C_SOURCE 200809L
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/mman.h>
#include <unistd.h>
#include <string.h>
#ifndef MAP_ANONYMOUS
# ifdef MAP_ANON
# define MAP_ANONYMOUS MAP_ANON
# else
# define MAP_ANONYMOUS 0x20 /* fallback: Linux value */
# endif
#endif
typedef struct {
uint8_t *base;
size_t size;
size_t used;
size_t guard_size;
} arena_t;
static int arena_init(arena_t *a, size_t bytes)
{
size_t pagesize = (size_t)sysconf(_SC_PAGESIZE);
size_t total = (bytes + pagesize - 1) / pagesize * pagesize + pagesize;
void *mem = mmap(NULL, total, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (mem == MAP_FAILED) return -1;
a->base = mem;
a->size = total - pagesize;
a->used = 0;
a->guard_size = pagesize;
uint8_t *guard = a->base + a->size;
if (mprotect(guard, pagesize, PROT_NONE) < 0) {
munmap(mem, total);
return -1;
}
return 0;
}
static void arena_destroy(arena_t *a)
{
if (!a->base) return;
size_t total = a->size + a->guard_size;
munmap(a->base, total);
a->base = NULL;
a->size = 0;
a->used = 0;
}
static void *arena_alloc(arena_t *a, size_t n)
{
size_t aligned = (n + sizeof(void *) - 1) & ~(sizeof(void *) - 1);
if (a->used + aligned > a->size) return NULL;
void *p = a->base + a->used;
a->used += aligned;
return p;
}
static void arena_reset(arena_t *a)
{
a->used = 0;
}
int main(void)
{
arena_t a;
if (arena_init(&a, 1 << 20) < 0) return 1;
char *s1 = arena_alloc(&a, 32);
char *s2 = arena_alloc(&a, 32);
strcpy(s1, "hello from arena");
strcpy(s2, "another string");
printf("%s | %s\n", s1, s2);
arena_reset(&a);
char *s3 = arena_alloc(&a, 64);
strcpy(s3, "after reset");
printf("%s\n", s3);
arena_destroy(&a);
return 0;
}