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); ...@@ -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 /* If passed as a flag to arena's mallocx()/reallocx() routines, the newly
* allocated memory will be 0-initialized. */ * allocated memory will be 0-initialized. */
#define AML_ARENA_FLAG_ZERO ((int)0x40) #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 */ /* opaque handle to configuration data */
struct aml_arena_data; struct aml_arena_data;
...@@ -271,6 +273,7 @@ struct aml_area_ops { ...@@ -271,6 +273,7 @@ struct aml_area_ops {
void *(*malloc)(struct aml_area_data *area, size_t size); void *(*malloc)(struct aml_area_data *area, size_t size);
void (*free)(struct aml_area_data *area, void *ptr); void (*free)(struct aml_area_data *area, void *ptr);
void *(*calloc)(struct aml_area_data *area, size_t num, size_t size); 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 *(*realloc)(struct aml_area_data *area, void *ptr, size_t size);
void *(*acquire)(struct aml_area_data *area, size_t size); void *(*acquire)(struct aml_area_data *area, size_t size);
void (*release)(struct aml_area_data *area, void *ptr); void (*release)(struct aml_area_data *area, void *ptr);
...@@ -711,6 +714,14 @@ void aml_area_free(struct aml_area *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. * 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); 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. * Changes the size of a previously allocated memory buffer.
* "area": an initialized memory area structure. * "area": an initialized memory area structure.
......
...@@ -25,6 +25,12 @@ void *aml_area_calloc(struct aml_area *area, size_t num, size_t size) ...@@ -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); 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) void *aml_area_realloc(struct aml_area *area, void *ptr, size_t size)
{ {
assert(area != NULL); assert(area != NULL);
......
...@@ -72,6 +72,25 @@ void *aml_area_linux_calloc(struct aml_area_data *a, size_t num, size_t size) ...@@ -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); 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) void *aml_area_linux_realloc(struct aml_area_data *a, void *ptr, size_t size)
{ {
assert(a != NULL); assert(a != NULL);
...@@ -121,6 +140,7 @@ struct aml_area_ops aml_area_linux_ops = { ...@@ -121,6 +140,7 @@ struct aml_area_ops aml_area_linux_ops = {
aml_area_linux_malloc, aml_area_linux_malloc,
aml_area_linux_free, aml_area_linux_free,
aml_area_linux_calloc, aml_area_linux_calloc,
aml_area_linux_memalign,
aml_area_linux_realloc, aml_area_linux_realloc,
aml_area_linux_acquire, aml_area_linux_acquire,
aml_area_linux_release, aml_area_linux_release,
......
...@@ -57,6 +57,13 @@ void *aml_area_posix_calloc(struct aml_area_data *data, size_t nm, size_t size) ...@@ -57,6 +57,13 @@ void *aml_area_posix_calloc(struct aml_area_data *data, size_t nm, size_t size)
return calloc(nm, 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) void *aml_area_posix_realloc(struct aml_area_data *data, void *ptr, size_t size)
{ {
assert(data != NULL); assert(data != NULL);
...@@ -79,6 +86,7 @@ struct aml_area_ops aml_area_posix_ops = { ...@@ -79,6 +86,7 @@ struct aml_area_ops aml_area_posix_ops = {
aml_area_posix_malloc, aml_area_posix_malloc,
aml_area_posix_free, aml_area_posix_free,
aml_area_posix_calloc, aml_area_posix_calloc,
aml_area_posix_memalign,
aml_area_posix_realloc, aml_area_posix_realloc,
aml_area_posix_acquire, aml_area_posix_acquire,
aml_area_posix_release, aml_area_posix_release,
......
...@@ -7,6 +7,7 @@ void doit(struct aml_area *area) ...@@ -7,6 +7,7 @@ void doit(struct aml_area *area)
{ {
void *ptr; void *ptr;
unsigned long *a, *b, *c; unsigned long *a, *b, *c;
intptr_t iptr;
/* try to allocate something */ /* try to allocate something */
ptr = aml_area_malloc(area, sizeof(unsigned long) * 10); ptr = aml_area_malloc(area, sizeof(unsigned long) * 10);
...@@ -30,6 +31,14 @@ void doit(struct aml_area *area) ...@@ -30,6 +31,14 @@ void doit(struct aml_area *area)
assert(a[0] == a[9]); assert(a[0] == a[9]);
aml_area_free(area, ptr); 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) */ /* libc API compatibility: calloc(0): same as malloc(0) */
ptr = aml_area_calloc(area, 0, sizeof(unsigned long)); ptr = aml_area_calloc(area, 0, sizeof(unsigned long));
aml_area_free(area, ptr); aml_area_free(area, ptr);
......
...@@ -7,6 +7,7 @@ int main(int argc, char *argv[]) ...@@ -7,6 +7,7 @@ int main(int argc, char *argv[])
void *ptr; void *ptr;
unsigned long *a, *b, *c; unsigned long *a, *b, *c;
unsigned long i; unsigned long i;
intptr_t iptr;
/* library initialization */ /* library initialization */
aml_init(&argc, &argv); aml_init(&argc, &argv);
...@@ -36,6 +37,13 @@ int main(int argc, char *argv[]) ...@@ -36,6 +37,13 @@ int main(int argc, char *argv[])
assert(a[0] == a[9]); assert(a[0] == a[9]);
aml_area_free(&area, ptr); 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) */ /* libc API compatibility: calloc(0): same as malloc(0) */
ptr = aml_area_calloc(&area, 0, sizeof(unsigned long)); ptr = aml_area_calloc(&area, 0, sizeof(unsigned long));
aml_area_free(&area, ptr); 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