-
Notifications
You must be signed in to change notification settings - Fork 41
/
malloc.c
71 lines (63 loc) · 1.74 KB
/
malloc.c
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
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
#include "ngs.h"
// Poor man's malloc. To be use only between fork() and exec().
int_fast8_t ngs_use_stupid_malloc;
void *ngs_malloc_base = 0;
void *ngs_malloc_next_free = 0;
size_t ngs_malloc_allocated = 0;
void ngs_malloc_init() {
long sz = sysconf(_SC_PAGESIZE);
ngs_malloc_allocated = 10*1024*1024;
assert(ngs_malloc_allocated % sz == 0);
ngs_malloc_base = mmap(NULL, ngs_malloc_allocated, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
if(ngs_malloc_base == (void *) -1) {
assert(0 == "MMAP FAILED");
}
assert(ngs_malloc_base);
ngs_malloc_next_free = ngs_malloc_base;
}
void *ngs_malloc(size_t size) {
void *p;
if(ngs_use_stupid_malloc) {
if(size % sizeof(size_t)) {
size = ((size / sizeof(size_t)) + 1) * sizeof(size_t);
}
assert(ngs_malloc_next_free - ngs_malloc_base + sizeof(size_t) + size < ngs_malloc_allocated);
*(size_t *)ngs_malloc_next_free = size;
ngs_malloc_next_free += sizeof(size_t);
p = ngs_malloc_next_free;
ngs_malloc_next_free += size;
memset(p, 0, size);
return p;
} else {
return GC_MALLOC(size);
}
}
void *ngs_malloc_atomic(size_t size) {
if(ngs_use_stupid_malloc) {
return ngs_malloc(size);
} else {
return GC_MALLOC_ATOMIC(size);
}
}
void *ngs_realloc(void *ptr, size_t size) {
if(ngs_use_stupid_malloc) {
if(ptr == NULL) {
return ngs_malloc(size);
}
if(ptr >= ngs_malloc_base && ptr < ngs_malloc_base + ngs_malloc_allocated) {
void *p = ngs_malloc(size);
memcpy(p, ptr, ((size_t *)ptr)[-1]);
return p;
}
assert(0 == "Realloc not implemented for NGS_STD_MALLOC_AFTER_FORK");
} else {
return GC_REALLOC(ptr, size);
}
}