diff options
author | Dan Albert <danalbert@google.com> | 2017-06-14 16:42:23 -0700 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2017-06-19 17:29:50 -0700 |
commit | 8bbe34dba669777d4a0850d44d8f3249d6a9ef43 (patch) | |
tree | 40259cadb0b09277dd81858e9a98493ce7052513 /sources | |
parent | a450754a5ce3dbb5146f2cbf803ae21457c69a56 (diff) | |
download | ndk-8bbe34dba669777d4a0850d44d8f3249d6a9ef43.tar.gz |
Add posix_memalign to libandroid_support.
Updating libc++ or libc++abi to HEAD will require this. We can drop
this once we drop ICS support (currently not planned).
Test: ./checkbuild.py && ./run_tests.py
Bug: None
Change-Id: Ia492762b0498c87600ac381dd278bf4399bd9eaa
Diffstat (limited to 'sources')
-rw-r--r-- | sources/android/support/Android.mk | 1 | ||||
-rw-r--r-- | sources/android/support/include/stdlib.h | 4 | ||||
-rw-r--r-- | sources/android/support/src/posix_memalign.cpp | 20 | ||||
-rw-r--r-- | sources/android/support/tests/Android.mk | 1 | ||||
-rw-r--r-- | sources/android/support/tests/posix_memalign_test.cpp | 40 |
5 files changed, 66 insertions, 0 deletions
diff --git a/sources/android/support/Android.mk b/sources/android/support/Android.mk index c508daaf2..7f594b0bf 100644 --- a/sources/android/support/Android.mk +++ b/sources/android/support/Android.mk @@ -66,6 +66,7 @@ android_support_sources := \ src/musl-stdio/vsprintf.c \ src/musl-stdio/vwprintf.c \ src/musl-stdio/wprintf.c \ + src/posix_memalign.cpp \ src/stdio/stdio_impl.c \ src/stdio/strtod.c \ src/stdio/vfprintf.c \ diff --git a/sources/android/support/include/stdlib.h b/sources/android/support/include/stdlib.h index 0b47898f2..58e5e0d1e 100644 --- a/sources/android/support/include/stdlib.h +++ b/sources/android/support/include/stdlib.h @@ -33,6 +33,10 @@ __BEGIN_DECLS +#if __ANDROID_API__ < 16 +int posix_memalign(void** memptr, size_t alignment, size_t size); +#endif + // These APIs made it in to L. #if __ANDROID_API__ < 21 diff --git a/sources/android/support/src/posix_memalign.cpp b/sources/android/support/src/posix_memalign.cpp new file mode 100644 index 000000000..cf7abbbf5 --- /dev/null +++ b/sources/android/support/src/posix_memalign.cpp @@ -0,0 +1,20 @@ +#include <errno.h> +#include <malloc.h> +#include <stdlib.h> + +int posix_memalign(void** memptr, size_t alignment, size_t size) { + if ((alignment & (alignment - 1)) != 0 || alignment == 0) { + return EINVAL; + } + + if (alignment % sizeof(void*) != 0) { + return EINVAL; + } + + *memptr = memalign(alignment, size); + if (*memptr == NULL) { + return errno; + } + + return 0; +} diff --git a/sources/android/support/tests/Android.mk b/sources/android/support/tests/Android.mk index b3d697e25..75ec1f81f 100644 --- a/sources/android/support/tests/Android.mk +++ b/sources/android/support/tests/Android.mk @@ -6,6 +6,7 @@ LOCAL_MODULE := android_support_unittests LOCAL_SRC_FILES := \ ctype_test.cpp \ math_test.cpp \ + posix_memalign_test.cpp \ stdio_test.cpp \ wchar_test.cpp \ diff --git a/sources/android/support/tests/posix_memalign_test.cpp b/sources/android/support/tests/posix_memalign_test.cpp new file mode 100644 index 000000000..61f4626ca --- /dev/null +++ b/sources/android/support/tests/posix_memalign_test.cpp @@ -0,0 +1,40 @@ +#include <gtest/gtest.h> + +TEST(stdlib, posix_memalign_sweep) { + void* ptr; + + // These should all fail. + for (size_t align = 0; align < sizeof(long); align++) { + ASSERT_EQ(EINVAL, posix_memalign(&ptr, align, 256)) + << "Unexpected value at align " << align; + } + + // Verify powers of 2 up to 2048 allocate, and verify that all other + // alignment values between the powers of 2 fail. + size_t last_align = sizeof(long); + for (size_t align = sizeof(long); align <= 2048; align <<= 1) { + // Try all of the non power of 2 values from the last until this value. + for (size_t fail_align = last_align + 1; fail_align < align; fail_align++) { + ASSERT_EQ(EINVAL, posix_memalign(&ptr, fail_align, 256)) + << "Unexpected success at align " << fail_align; + } + ASSERT_EQ(0, posix_memalign(&ptr, align, 256)) + << "Unexpected failure at align " << align; + ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & (align - 1)) + << "Did not return a valid aligned ptr " << ptr << " expected alignment " << align; + free(ptr); + last_align = align; + } +} + +TEST(stdlib, posix_memalign_various_sizes) { + std::vector<size_t> sizes{1, 4, 8, 256, 1024, 65000, 128000, 256000, 1000000}; + for (auto size : sizes) { + void* ptr; + ASSERT_EQ(0, posix_memalign(&ptr, 16, 1)) + << "posix_memalign failed at size " << size; + ASSERT_EQ(0U, reinterpret_cast<uintptr_t>(ptr) & 0xf) + << "Pointer not aligned at size " << size << " ptr " << ptr; + free(ptr); + } +} |