diff --git a/src/aml.h b/src/aml.h index 8450c3192b7f9bf4c5ecf128405da4db51e7d6ad..3bc04924c97a8a507fdf78b4b4278eb5932bcb49 100644 --- a/src/aml.h +++ b/src/aml.h @@ -126,6 +126,8 @@ int aml_vector_destroy(struct aml_vector *vector); /* If passed as a flag to arena's mallocx()/reallocx() routines, the newly * allocated memory will be 0-initialized. */ #define AML_ARENA_FLAG_ZERO ((int)0x40) +/* As a flag to arena mallocx/reallocx, will align on (1<ops->calloc(area->data, num, size); } +void *aml_area_memalign(struct aml_area *area, size_t align, size_t size) +{ + assert(area != NULL); + return area->ops->memalign(area->data, align, size); +} + void *aml_area_realloc(struct aml_area *area, void *ptr, size_t size) { assert(area != NULL); diff --git a/src/area_linux.c b/src/area_linux.c index 73b2bab878d6007bd23b46a42980a6b08a91c577..1f123bc38bb4fbf37b81ff34b523e6662a58e928 100644 --- a/src/area_linux.c +++ b/src/area_linux.c @@ -72,6 +72,25 @@ void *aml_area_linux_calloc(struct aml_area_data *a, size_t num, size_t size) return aml_area_linux_malloc(a, num*size); } +void *aml_area_linux_memalign(struct aml_area_data *a, size_t align, + size_t size) +{ + assert(a != NULL); + struct aml_area_linux *area = (struct aml_area_linux *)a; + struct aml_arena *arena = (struct aml_arena *) + area->ops.manager.get_arena(&area->data.manager); + void *ret; + assert(arena != NULL); + if(size == 0) + return NULL; + + area->ops.mbind.pre_bind(&area->data.mbind); + ret = aml_arena_mallocx(arena, size, AML_ARENA_FLAG_ZERO | + AML_ARENA_FLAG_ALIGN(align)); + area->ops.mbind.post_bind(&area->data.mbind, ret, size); + return ret; +} + void *aml_area_linux_realloc(struct aml_area_data *a, void *ptr, size_t size) { assert(a != NULL); @@ -121,6 +140,7 @@ struct aml_area_ops aml_area_linux_ops = { aml_area_linux_malloc, aml_area_linux_free, aml_area_linux_calloc, + aml_area_linux_memalign, aml_area_linux_realloc, aml_area_linux_acquire, aml_area_linux_release, diff --git a/src/area_posix.c b/src/area_posix.c index a1001dda8d3ca9e3019c6cf3b7c095ea11a0858d..365f91b75171c9f0edaabe2a98d8754ac99628a5 100644 --- a/src/area_posix.c +++ b/src/area_posix.c @@ -57,6 +57,13 @@ void *aml_area_posix_calloc(struct aml_area_data *data, size_t nm, size_t size) return calloc(nm, size); } +void *aml_area_posix_memalign(struct aml_area_data *data, size_t align, + size_t size) +{ + assert(data != NULL); + return aligned_alloc(align, size); +} + void *aml_area_posix_realloc(struct aml_area_data *data, void *ptr, size_t size) { assert(data != NULL); @@ -79,6 +86,7 @@ struct aml_area_ops aml_area_posix_ops = { aml_area_posix_malloc, aml_area_posix_free, aml_area_posix_calloc, + aml_area_posix_memalign, aml_area_posix_realloc, aml_area_posix_acquire, aml_area_posix_release, diff --git a/tests/area_linux.c b/tests/area_linux.c index 470452676d4491db8c9b16850d3a2608ac45b82d..afd9868347475976c70bc08564553d0380d52f09 100644 --- a/tests/area_linux.c +++ b/tests/area_linux.c @@ -7,6 +7,7 @@ void doit(struct aml_area *area) { void *ptr; unsigned long *a, *b, *c; + intptr_t iptr; /* try to allocate something */ ptr = aml_area_malloc(area, sizeof(unsigned long) * 10); @@ -30,6 +31,14 @@ void doit(struct aml_area *area) assert(a[0] == a[9]); aml_area_free(area, ptr); + /* memalign */ + ptr = aml_area_memalign(area, 16, sizeof(unsigned long)); + assert(ptr != NULL); + iptr = ptr; + assert(iptr % 16 == 0); + aml_area_free(area, ptr); + + /* libc API compatibility: calloc(0): same as malloc(0) */ ptr = aml_area_calloc(area, 0, sizeof(unsigned long)); aml_area_free(area, ptr); diff --git a/tests/area_posix.c b/tests/area_posix.c index 6ae15534e65dadef28cbacb6d42313f078366cc1..b2b76b35b73def2b4fb50b1f1a7154e2fe298f7e 100644 --- a/tests/area_posix.c +++ b/tests/area_posix.c @@ -7,6 +7,7 @@ int main(int argc, char *argv[]) void *ptr; unsigned long *a, *b, *c; unsigned long i; + intptr_t iptr; /* library initialization */ aml_init(&argc, &argv); @@ -36,6 +37,13 @@ int main(int argc, char *argv[]) assert(a[0] == a[9]); aml_area_free(&area, ptr); + /* memalign */ + ptr = aml_area_memalign(&area, 16, sizeof(unsigned long)); + assert(ptr != NULL); + iptr = ptr; + assert(iptr % 16 == 0); + aml_area_free(&area, ptr); + /* libc API compatibility: calloc(0): same as malloc(0) */ ptr = aml_area_calloc(&area, 0, sizeof(unsigned long)); aml_area_free(&area, ptr);