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