Commit 22d43bfd authored by Swann Perarnau's avatar Swann Perarnau

[feature] add memalign function for areas

This patch provides aligned allocations for all areas. Simple tests
included.

Note that I haven't tested if it conflicts with arena-wide alignements.
parent a0b93401
Pipeline #6988 passed with stage
in 8 minutes and 3 seconds
......@@ -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<<a). */
#define AML_ARENA_FLAG_ALIGN(a) ((int)(a))
/* opaque handle to configuration data */
struct aml_arena_data;
......@@ -271,6 +273,7 @@ struct aml_area_ops {
void *(*malloc)(struct aml_area_data *area, size_t size);
void (*free)(struct aml_area_data *area, void *ptr);
void *(*calloc)(struct aml_area_data *area, size_t num, size_t size);
void *(*memalign)(struct aml_area_data *area, size_t align, size_t size);
void *(*realloc)(struct aml_area_data *area, void *ptr, size_t size);
void *(*acquire)(struct aml_area_data *area, size_t size);
void (*release)(struct aml_area_data *area, void *ptr);
......@@ -711,6 +714,14 @@ void aml_area_free(struct aml_area *area, void *ptr);
* Returns a pointer to the newly allocated memory buffer; NULL if unsuccessful.
*/
void *aml_area_calloc(struct aml_area *area, size_t num, size_t size);
/*
* Allocates a new, aligned, memory buffer from a memory area.
* "area": an initialized memory area structure.
* "align": an alignment for the returned pointer.
* "size": the buffer size in bytes; if 0 is passed, NULL will be returned.
* Returns a pointer to the newly allocated memory buffer; NULL if unsuccessful.
*/
void *aml_area_memalign(struct aml_area *area, size_t align, size_t size);
/*
* Changes the size of a previously allocated memory buffer.
* "area": an initialized memory area structure.
......
......@@ -25,6 +25,12 @@ void *aml_area_calloc(struct aml_area *area, size_t num, size_t size)
return area->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);
......
......@@ -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,
......
......@@ -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,
......
......@@ -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);
......
......@@ -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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment