aboutsummaryrefslogtreecommitdiff
path: root/sources
diff options
context:
space:
mode:
authorDan Albert <danalbert@google.com>2017-06-14 16:42:23 -0700
committerDan Albert <danalbert@google.com>2017-06-19 17:29:50 -0700
commit8bbe34dba669777d4a0850d44d8f3249d6a9ef43 (patch)
tree40259cadb0b09277dd81858e9a98493ce7052513 /sources
parenta450754a5ce3dbb5146f2cbf803ae21457c69a56 (diff)
downloadndk-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.mk1
-rw-r--r--sources/android/support/include/stdlib.h4
-rw-r--r--sources/android/support/src/posix_memalign.cpp20
-rw-r--r--sources/android/support/tests/Android.mk1
-rw-r--r--sources/android/support/tests/posix_memalign_test.cpp40
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);
+ }
+}