commit 9151d9e75f5a52e009395f480745b79f52d2ead4
parent a89fd0d09603bd8db245064cda62891b154ba64c
Author: sin <sin@2f30.org>
Date:   Fri,  2 Aug 2013 12:32:48 +0100
Ensure posix_memalign() returns correctly aligned addresses
If we re-use a block from the free tree then make sure the
address is aligned properly.
Diffstat:
| M | random/rballoc.c |  |  | 78 | ++++++++++++++++++++++++++++++++++++++++++------------------------------------ | 
1 file changed, 42 insertions(+), 36 deletions(-)
diff --git a/random/rballoc.c b/random/rballoc.c
@@ -108,8 +108,8 @@ mmap_aligned(size_t align, size_t siz)
 	return p;
 }
 
-static void *
-aligned_malloc(size_t align, size_t siz)
+void *
+malloc(size_t siz)
 {
 	struct node n, *an, *res;
 	void *p;
@@ -129,7 +129,7 @@ aligned_malloc(size_t align, size_t siz)
 			unlock(&rblock);
 			return NULL;
 		}
-		p = mmap_aligned(align, siz);
+		p = mmap_aligned(MINALIGNMENT, siz);
 		if (!p) {
 			unlock(&rblock);
 			return NULL;
@@ -147,12 +147,6 @@ aligned_malloc(size_t align, size_t siz)
 }
 
 void *
-malloc(size_t siz)
-{
-	return aligned_malloc(MINALIGNMENT, siz);
-}
-
-void *
 realloc(void *oldp, size_t siz)
 {
 	struct node n, *res;
@@ -252,19 +246,55 @@ free(void *p)
 int
 posix_memalign(void **memptr, size_t align, size_t siz)
 {
-	void *mem;
+	void *mem, *new;
+	struct node n, *res;
 
 	if (((align - 1) & align))
 		return EINVAL;
 	if (align < sizeof(void *))
 		return EINVAL;
-	mem = aligned_malloc(align, siz);
+	mem = malloc(siz + align);
 	if (!mem)
 		return ENOMEM;
-	*memptr = mem;
+	new = (void *)(((uintptr_t)mem + align) & ~(align - 1));
+	if (new == mem) {
+		*memptr = mem;
+		return 0;
+	}
+	lock(&rblock);
+	n.buf = mem;
+	res = RB_FIND(alloc_tree, &at, &n);
+	res->buf = new;
+	res->siz -= ((uintptr_t)new - (uintptr_t)mem);
+	unlock(&rblock);
+	*memptr = new;
+	return 0;
+}
+
+size_t
+malloc_usable_size(void *p)
+{
+	struct node n, *res;
+
+	if (!p)
+		return 0;
+	lock(&rblock);
+	n.buf = p;
+	res = RB_FIND(alloc_tree, &at, &n);
+	if (res) {
+		unlock(&rblock);
+		return res->siz;
+	}
+	unlock(&rblock);
 	return 0;
 }
 
+size_t
+malloc_size(void *p)
+{
+	return malloc_usable_size(p);
+}
+
 void *
 memalign(size_t align, size_t siz)
 {
@@ -292,27 +322,3 @@ valloc(size_t siz)
 	fprintf(stderr, "%s: not implemented!\n", __func__);
 	abort();
 }
-
-size_t
-malloc_usable_size(void *p)
-{
-	struct node n, *res;
-
-	if (!p)
-		return 0;
-	lock(&rblock);
-	n.buf = p;
-	res = RB_FIND(alloc_tree, &at, &n);
-	if (res) {
-		unlock(&rblock);
-		return res->siz;
-	}
-	unlock(&rblock);
-	return 0;
-}
-
-size_t
-malloc_size(void *p)
-{
-	return malloc_usable_size(p);
-}