commit bc1547ffc9669d20f33a226454a01114238c6f78
parent b449c241c99e6419a552da53cd0c868920c740cd
Author: vaplv <vincent.forest@meso-star.com>
Date: Thu, 1 Dec 2016 10:04:05 +0100
Add and test the DARRAY_ALIGNMENT generic attribute
Define the alignment of the dynamic array.
Diffstat:
2 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/src/dynamic_array.h b/src/dynamic_array.h
@@ -29,6 +29,8 @@
* following macros:
* - DARRAY_NAME: prefix of the dynamic array functions & types;
* - DARRAY_DATA: type of the data registered into the array;
+ * - DARRAY_ALIGNMENT: alignment of the array address. Must be a power of two.
+ * If not defined, used the default system alignment.
* - DARRAY_FUNCTOR_INIT: init functor on DARRAY_DATA. If not defined, no
* specific treatment is performed on the created data;
* - DARRAY_FUNCTOR_COPY: copy functor on DARRAY_DATA. If not defined a
@@ -52,6 +54,15 @@
#define DARRAY_FUNC__(Func) CONCAT(CONCAT(CONCAT(darray_, DARRAY_NAME),_), Func)
#define DARRAY_TYPE__ CONCAT(darray_, DARRAY_NAME)
+#ifndef DARRAY_ALIGNMENT
+ #define DARRAY_ALIGNMENT__ MMAX(ALIGNOF(DARRAY_DATA), 16)
+#else
+ STATIC_ASSERT(IS_POW2(DARRAY_ALIGNMENT),
+ DARRAY_ALIGNMENT_must_be_a_power_of_2);
+ #define DARRAY_ALIGNMENT__\
+ MMAX(ALIGNOF(DARRAY_DATA), MMAX(DARRAY_ALIGNMENT, 16))
+#endif
+
struct DARRAY_TYPE__ {
DARRAY_DATA* data;
/* Avoids alloc on small arrays. The CL compiler does not support the use of
@@ -60,7 +71,7 @@ struct DARRAY_TYPE__ {
#ifdef COMPILER_CL
char buf[1];
#else
- char ALIGN(MMIN(ALIGNOF(DARRAY_DATA), 16)) buf[16*sizeof(DARRAY_DATA)];
+ char ALIGN(DARRAY_ALIGNMENT__) buf[16*sizeof(DARRAY_DATA)];
#endif
size_t size;
size_t capacity;
@@ -157,7 +168,7 @@ DARRAY_FUNC__(reserve)(struct DARRAY_TYPE__* darray, const size_t sz)
data = (DARRAY_DATA*)MEM_ALLOC_ALIGNED
(darray->allocator,
sz_adjusted * sizeof(DARRAY_DATA),
- MMIN(ALIGNOF(DARRAY_DATA), 16));
+ DARRAY_ALIGNMENT__);
if(!data)
return RES_MEM_ERR;
@@ -385,12 +396,14 @@ DARRAY_FUNC__(swap)(struct DARRAY_TYPE__* a, struct DARRAY_TYPE__* b)
return RES_OK;
}
+#undef DARRAY_ALIGNMENT
#undef DARRAY_NAME
#undef DARRAY_DATA
#undef DARRAY_FUNCTOR_INIT
#undef DARRAY_FUNCTOR_RELEASE
#undef DARRAY_FUNCTOR_COPY
#undef DARRAY_FUNCTOR_COPY_AND_RELEASE
+#undef DARRAY_ALIGNMENT__
#undef DARRAY_FUNC__
#undef DARRAY_TYPE__
diff --git a/src/test_dynamic_array.c b/src/test_dynamic_array.c
@@ -310,6 +310,51 @@ test_swap_string
#undef PUSH_BACK
}
+#define DARRAY_NAME byte
+#define DARRAY_DATA char
+#include "dynamic_array.h"
+
+#define DARRAY_NAME byte64
+#define DARRAY_DATA char
+#define DARRAY_ALIGNMENT 64
+#include "dynamic_array.h"
+
+#define DARRAY_NAME byte1K
+#define DARRAY_DATA char
+#define DARRAY_ALIGNMENT 1024
+#include "dynamic_array.h"
+
+static void
+test_alignment(struct mem_allocator* allocator)
+{
+ struct darray_byte bytes;
+ struct darray_byte64 bytes64;
+ struct darray_byte1K bytes1K;
+
+ NCHECK(allocator, NULL);
+
+ darray_byte_init(allocator, &bytes);
+ CHECK(darray_byte_resize(&bytes, 2), RES_OK);
+ CHECK(IS_ALIGNED(darray_byte_cdata_get(&bytes), ALIGNOF(char)), 1);
+ CHECK(darray_byte_resize(&bytes, 314159), RES_OK);
+ CHECK(IS_ALIGNED(darray_byte_cdata_get(&bytes), ALIGNOF(char)), 1);
+ darray_byte_release(&bytes);
+
+ darray_byte64_init(allocator, &bytes64);
+ CHECK(darray_byte64_resize(&bytes64, 2), RES_OK);
+ CHECK(IS_ALIGNED(darray_byte64_cdata_get(&bytes64), 64), 1);
+ CHECK(darray_byte64_resize(&bytes64, 314159), RES_OK);
+ CHECK(IS_ALIGNED(darray_byte64_cdata_get(&bytes64), 64), 1);
+ darray_byte64_release(&bytes64);
+
+ darray_byte1K_init(allocator, &bytes1K);
+ CHECK(darray_byte1K_resize(&bytes1K, 2), RES_OK);
+ CHECK(IS_ALIGNED(darray_byte1K_cdata_get(&bytes1K), 1024), 1);
+ CHECK(darray_byte1K_resize(&bytes1K, 314159), RES_OK);
+ CHECK(IS_ALIGNED(darray_byte1K_cdata_get(&bytes1K), 1024), 1);
+ darray_byte1K_release(&bytes1K);
+}
+
int
main(int argc, char** argv)
{
@@ -329,6 +374,8 @@ main(int argc, char** argv)
test_swap_string(&mem_default_allocator, &allocator_proxy);
test_swap_string(&allocator_proxy, &allocator_proxy);
+ test_alignment(&mem_default_allocator);
+
check_memory_allocator(&allocator_proxy);
mem_shutdown_proxy_allocator(&allocator_proxy);
CHECK(mem_allocated_size(), 0);