-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmmalloc.c
92 lines (71 loc) · 2.09 KB
/
mmalloc.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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#include "mmalloc.h"
#include <sys/mman.h>
#include "abstract_data/kernel.h"
#include "debug.h"
#include <sys/ptrace.h>
#include "linux_syscall_support.h"
/**
* Align to the nearest lower address
*
* @param size Address or size to be aligned.
* @param align Size of alignment, must be power of 2.
*/
#define ALIGN_DOWN(size, align) ((size) & ~((align) - 1))
/**
* Align to the nearest higher address
*
* @param size Address or size to be aligned.
* @param align Size of alignment, must be power of 2.
*/
#define ALIGN_UP(size, align) (((size) + ((align) - 1)) & ~((align) - 1))
/** Default memory alignment used */
#define MMALLOC_ALIGNMENT 8
/** Default memory allocation quantum */
#define MMALLOC_QUANTUM (1 << 16) //4096
struct mheader {
size_t size;
size_t used;
void *bump;
};
static struct mheader *last = NULL;
void *mmalloc(size_t size) {
//dprint("size %zu\n", size);
size = ALIGN_UP(size, MMALLOC_ALIGNMENT);
if (last) {
size_t avail = (void *)last + last->size - last->bump;
if (avail >= size) {
void *p = last->bump;
last->bump = last->bump + size;
last->used += size;
return p;
}
}
// We need a bit more to have a space for header structure.
size_t len = ALIGN_UP(size + sizeof(struct mheader), MMALLOC_QUANTUM);
// Allocate new header through mmap system call.
struct mheader *header = (struct mheader *)mmap(NULL, len,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (header == MAP_FAILED) {
return NULL;
}
if (len - sizeof(struct mheader) - size >= MMALLOC_ALIGNMENT) {
last = header;
}
header->size = len;
header->used = size;
void *p = (void *)header + sizeof(struct mheader);
header->bump = p + size;
return p;
}
void mfree(void *ptr, size_t size) {
if (!ptr)
return;
size_t len = ALIGN_UP(size, MMALLOC_ALIGNMENT);
void *p = (void *) ALIGN_DOWN((uintptr_t)ptr, MMALLOC_QUANTUM);
struct mheader *header = (struct mheader *)p;
header->used -= len;
// Free header after last allocation has been freed.
if (!header->used) {
munmap(header, header->size);
}
}