blob: 0cf9af62e468a53121b01da4aec3b4d01ee95e43 (
plain)
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
|
#include "allocator.h"
#include <stdlib.h>
#include <sys/mman.h>
#include <unistd.h>
size_t align(size_t size, size_t al)
{
size_t padding = size % al;
if (padding)
padding = al - padding;
size_t res;
if (__builtin_uaddl_overflow(size, padding, &res))
return 0;
return res;
}
struct blk_allocator *blka_new(void)
{
struct blk_allocator *new = malloc(sizeof(struct blk_allocator));
new->meta = NULL;
return new;
}
struct blk_meta *blka_alloc(struct blk_allocator *blka, size_t size)
{
long page_size = sysconf(_SC_PAGESIZE);
size_t aligned_size = align(size + sizeof(struct blk_meta), page_size);
struct blk_meta *meta = mmap(NULL, aligned_size, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (meta == MAP_FAILED)
return NULL;
meta->size = aligned_size - sizeof(struct blk_meta);
meta->next = blka->meta;
blka->meta = meta;
return meta;
}
void blka_free(struct blk_meta *blk)
{
munmap(blk, blk->size + sizeof(struct blk_meta));
}
void blka_pop(struct blk_allocator *blka)
{
if (blka->meta == NULL)
return;
struct blk_meta *meta = blka->meta;
blka->meta = blka->meta->next;
blka_free(meta);
}
void blka_delete(struct blk_allocator *blka)
{
while (blka->meta)
{
blka_pop(blka);
}
free(blka);
}
|