commit faf44fd5917251a56e5264e238417d06d5dd288f
parent 64c09e5c2a77312abc0c4e18cdc3751e93748089
Author: sin <sin@2f30.org>
Date:   Fri,  2 Aug 2013 11:27:09 +0100
Switch to sbrk() instead of mmap()
Allow for allocating memory at a particularly aligned address.
Diffstat:
1 file changed, 22 insertions(+), 19 deletions(-)
diff --git a/random/rballoc.c b/random/rballoc.c
@@ -5,6 +5,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <stdint.h>
 #include <errno.h>
 #include "tree.h"
 #include "spinlock.h"
@@ -90,23 +91,24 @@ alloc_object(size_t siz)
 	return sd.base;
 }
 
-/* Allocate a memory block.  Round `siz' to be
- * a multiple of PAGESIZE */
 static void *
-alloc_block(size_t siz)
+sbrk_aligned(size_t align, size_t siz)
 {
-	void *addr;
+	char *p;
 
-	siz = PAGESIZE * ((siz + PAGESIZE - 1) / PAGESIZE);
-	addr = mmap(0, siz, PROT_READ | PROT_WRITE,
-		    MAP_PRIVATE | MAP_ANON, -1, 0);
-	if (addr == MAP_FAILED)
+	if ((align - 1) & align)
 		return NULL;
-	return addr;
+	sd.base = sbrk(siz + align);
+	if (sd.base == (void *)-1)
+		return NULL;
+	sd.siz += siz + align;
+	p = sd.base;
+	p = (char *)(((uintptr_t)p + align) & ~(align - 1));
+	return p;
 }
 
-void *
-malloc(size_t siz)
+static void *
+aligned_malloc(size_t align, size_t siz)
 {
 	struct node n, *an, *res;
 	void *p;
@@ -126,7 +128,7 @@ malloc(size_t siz)
 			unlock(&rblock);
 			return NULL;
 		}
-		p = alloc_block(siz);
+		p = sbrk_aligned(align, siz);
 		if (!p) {
 			unlock(&rblock);
 			return NULL;
@@ -144,6 +146,12 @@ malloc(size_t siz)
 }
 
 void *
+malloc(size_t siz)
+{
+	return aligned_malloc(PAGESIZE, siz);
+}
+
+void *
 realloc(void *oldp, size_t siz)
 {
 	struct node n, *res;
@@ -180,7 +188,7 @@ realloc(void *oldp, size_t siz)
 				unlock(&rblock);
 				return NULL;
 			}
-			newan->buf = alloc_block(siz);
+			newan->buf = sbrk_aligned(PAGESIZE, siz);
 			if (!newan->buf) {
 				free_object(newan, sizeof(*newan));
 				unlock(&rblock);
@@ -249,12 +257,7 @@ posix_memalign(void **memptr, size_t align, size_t siz)
 		return EINVAL;
 	if (align < sizeof(void *))
 		return EINVAL;
-	if (PAGESIZE % align) {
-		fprintf(stderr, "%s: %zu alignment not supported!\n",
-			__func__, align);
-		abort();
-	}
-	mem = malloc(siz);
+	mem = aligned_malloc(align, siz);
 	if (!mem)
 		return ENOMEM;
 	*memptr = mem;