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;
}