From 084cb5cc7d3d09a61d9d345fc15c78912dac9bd4 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 17 May 2023 12:50:03 -0700 Subject: [PATCH 1/2] libc/common: Add memalign Memalign is another name for the posix aligned_alloc function, although it has weaker restrictions on the relationship between the alignment and size. memalign() is used internally by the libstdc++ when built for 'newlib' targets (which includes picolibc) instead of aligned_alloc() due to a bug in gcc, so we need to provide an implementation of this when using that library, even though it's not part of the Zephyr C library API. When a fix for the libstdc++ is merged upstream and can be consider a reasonable dependency for Zephyr, this work-around can be removed. Closes: #57899 Signed-off-by: Keith Packard --- lib/libc/common/source/stdlib/malloc.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/lib/libc/common/source/stdlib/malloc.c b/lib/libc/common/source/stdlib/malloc.c index 02354cd194dc9e..50c688fa7f21bd 100644 --- a/lib/libc/common/source/stdlib/malloc.c +++ b/lib/libc/common/source/stdlib/malloc.c @@ -153,6 +153,27 @@ void *aligned_alloc(size_t alignment, size_t size) return ret; } +#ifdef CONFIG_GLIBCXX_LIBCPP + +/* + * GCC's libstdc++ may use this function instead of aligned_alloc due to a + * bug in the configuration for "newlib" environments (which includes picolibc). + * When toolchains including that bug fix can become a dependency for Zephyr, + * this work-around can be removed. + * + * Note that aligned_alloc isn't defined to work as a replacement for + * memalign as it requires that the size be a multiple of the alignment, + * while memalign does not. However, the aligned_alloc implementation here + * is just a wrapper around sys_heap_aligned_alloc which doesn't have that + * requirement and so can be used by memalign. + */ + +void *memalign(size_t alignment, size_t size) +{ + return aligned_alloc(alignment, size); +} +#endif + static int malloc_prepare(void) { void *heap_base = NULL; From 112fad1dd788949c880ca7ce6c070aeba5821610 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Wed, 17 May 2023 17:44:40 -0700 Subject: [PATCH 2/2] tests/libcxx: Test aligned allocation with C++ new operator Make sure the underlying allocation system can support an allocation request generated by the new operator which has stricter alignment requirements than the default. For G++, this ends up using the 'memalign' function which is not part of any C standard. Signed-off-by: Keith Packard --- tests/lib/cpp/libcxx/prj.conf | 1 + tests/lib/cpp/libcxx/src/main.cpp | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/tests/lib/cpp/libcxx/prj.conf b/tests/lib/cpp/libcxx/prj.conf index 043fb1391b3708..fff9acb3adca15 100644 --- a/tests/lib/cpp/libcxx/prj.conf +++ b/tests/lib/cpp/libcxx/prj.conf @@ -2,4 +2,5 @@ CONFIG_CPP=y CONFIG_STD_CPP17=y CONFIG_ZTEST=y CONFIG_ZTEST_STACK_SIZE=5120 +CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=32768 CONFIG_ZTEST_NEW_API=y diff --git a/tests/lib/cpp/libcxx/src/main.cpp b/tests/lib/cpp/libcxx/src/main.cpp index 3151aaae892d0f..d1d7d37af18840 100644 --- a/tests/lib/cpp/libcxx/src/main.cpp +++ b/tests/lib/cpp/libcxx/src/main.cpp @@ -9,6 +9,7 @@ #include #include #include +#include BUILD_ASSERT(__cplusplus == 201703); @@ -95,6 +96,17 @@ ZTEST(libcxx_tests, test_exception) } #endif +struct ThreadStack +{ + K_KERNEL_STACK_MEMBER(threadStack, 1024) {}; +}; + +ZTEST(libcxx_tests, test_new_aligned) +{ + auto test_aligned = std::make_unique(); + zassert_not_null(test_aligned, "aligned allocation failed"); +} + static void *libcxx_tests_setup(void) { TC_PRINT("version %u\n", (uint32_t)__cplusplus);