commit 349b0a2660be259803da88a83a094e465dd40005
parent 21f224de6c5c2f95f18b4cd4e1f930632a7d9d85
Author: sin <sin@2f30.org>
Date:   Fri,  2 Aug 2013 13:43:07 +0100
Make posix_memalign() less hack-ish
Remove sbrk_descr, not really needed.
Diffstat:
1 file changed, 24 insertions(+), 27 deletions(-)
diff --git a/random/rballoc.c b/random/rballoc.c
@@ -72,23 +72,15 @@ dump_free_tree(void)
 			__func__, n->buf, n->siz);
 }
 
-struct sbrk_descr {
-	void *base;
-	size_t siz;
-};
-
-static struct sbrk_descr sd;
-
 static inline void *
 alloc_object(size_t siz)
 {
-	void *p;
+	void *base, *p;
 
-	sd.base = sbrk(siz + MINALIGNMENT);
-	if (sd.base == (void *)-1)
+	base = sbrk(siz + MINALIGNMENT);
+	if (base == (void *)-1)
 		return NULL;
-	sd.siz += siz + MINALIGNMENT;
-	p = sd.base;
+	p = base;
 	p = (void *)(((uintptr_t)p + MINALIGNMENT) & ~(MINALIGNMENT - 1));
 	return p;
 }
@@ -246,29 +238,34 @@ free(void *p)
 int
 posix_memalign(void **memptr, size_t align, size_t siz)
 {
-	void *mem, *new;
-	struct node n, *res;
+	struct node *an;
+	void *p;
 
+	*memptr = NULL;
 	if (((align - 1) & align))
 		return EINVAL;
 	if (align < sizeof(void *))
 		return EINVAL;
-	mem = malloc(siz + align);
-	if (!mem)
-		return ENOMEM;
-	new = (void *)(((uintptr_t)mem + align) & ~(align - 1));
-	if (new == mem) {
-		*memptr = mem;
+	if (!siz)
 		return 0;
-	}
+	/* Just allocate a new block, we don't care to look
+	 * for a block in the free tree as it might not be properly
+	 * aligned.  The previous implementation could cope with
+	 * that but it was sort of hackish.  There are few calls to
+	 * posix_memalign() in most cases, so the overhead should
+	 * not really matter. */
+	an = alloc_object(sizeof(*an));
+	if (!an)
+		return ENOMEM;
+	p = mmap_aligned(align, siz);
+	if (!p)
+		return ENOMEM;
+	an->buf = p;
+	an->siz = siz;
 	lock(&rblock);
-	n.buf = mem;
-	res = RB_FIND(alloc_tree, &at, &n);
-	/* Use an offset here? */
-	res->buf = new;
-	res->siz -= ((uintptr_t)new - (uintptr_t)mem);
+	RB_INSERT(alloc_tree, &at, an);
 	unlock(&rblock);
-	*memptr = new;
+	*memptr = p;
 	return 0;
 }