commit fcacada2e7f64a6bee74dec823fd82377e16e170
parent 4a6c259f4a924d5fc7ad60fa7ee742037e194e47
Author: sin <sin@2f30.org>
Date: Tue, 30 Jul 2013 10:35:51 +0100
Use mmap() instead of sbrk()
Diffstat:
M | alloc.c | | | 32 | +++++++++++++++++++++++++++++--- |
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/alloc.c b/alloc.c
@@ -1,3 +1,4 @@
+#include <sys/mman.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -10,7 +11,7 @@ enum chunk_state {
/* A maximum of `NALLOC' allocations possible */
enum {
- NALLOC = 65536 * 64,
+ NALLOC = 65536 * 128,
};
/* Only needed because we have to implement
@@ -22,6 +23,29 @@ struct chunk {
} chunks[NALLOC];
void *
+mmap_page_aligned(size_t nbytes)
+{
+ void *addr;
+ int ret;
+
+ if (nbytes % 0x1000)
+ nbytes = (nbytes + 0x1000) & ~(0x1000 - 1);
+
+ addr = mmap(0, nbytes + 0x1000,
+ PROT_READ | PROT_WRITE,
+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+ if (addr == MAP_FAILED)
+ return NULL;
+ ret = mprotect((char *)addr + nbytes, 0x1000,
+ PROT_NONE);
+ if (ret < 0) {
+ munmap(addr, nbytes + 0x1000);
+ return NULL;
+ }
+ return addr;
+}
+
+void *
malloc(size_t nbytes)
{
void *p;
@@ -29,8 +53,8 @@ malloc(size_t nbytes)
if (!nbytes)
return NULL;
- p = sbrk(nbytes);
- if (p == (void *)-1)
+ p = mmap_page_aligned(nbytes);
+ if (!p)
return NULL;
for (i = 0; i < NALLOC; i++) {
if (chunks[i].state == FREE) {
@@ -62,6 +86,7 @@ realloc(void *oldp, size_t nbytes)
n = chunks[i].size < nbytes ? chunks[i].size : nbytes;
memcpy(p, chunks[i].base, n);
chunks[i].state = FREE;
+ munmap(chunks[i].base, chunks[i].size + 0x1000);
return p;
}
}
@@ -90,6 +115,7 @@ free(void *p)
for (i = 0; i < NALLOC; i++) {
if (chunks[i].base == p) {
chunks[i].state = FREE;
+ munmap(chunks[i].base, chunks[i].size + 0x1000);
break;
}
}