Add aligned_alloc to libc.
Bug: 72969374
Test: Bionic unit tests pass.
Test: Malloc debug unit tests pass.
Change-Id: I235985bbc638855d94249c97c98f14ab2924bda0
(cherry picked from commit d69ee59594088c0d92ba9273188ef53ea5e6cd6a)
diff --git a/libc/malloc_debug/README.md b/libc/malloc_debug/README.md
index b7a12a5..69d0648 100644
--- a/libc/malloc_debug/README.md
+++ b/libc/malloc_debug/README.md
@@ -23,6 +23,7 @@
* `realloc`
* `posix_memalign`
* `memalign`
+* `aligned_alloc`
* `malloc_usable_size`
On 32 bit systems, these two deprecated functions are also replaced:
@@ -324,6 +325,10 @@
**THREAD\_ID**: memalign pointer alignment size
+pointer = aligned\_alloc(alignment, size)
+
+**THREAD\_ID**: memalign pointer alignment size
+
posix\_memalign(&pointer, alignment, size)
**THREAD\_ID**: memalign pointer alignment size
diff --git a/libc/malloc_debug/RecordData.cpp b/libc/malloc_debug/RecordData.cpp
index 55d9943..8e9c671 100644
--- a/libc/malloc_debug/RecordData.cpp
+++ b/libc/malloc_debug/RecordData.cpp
@@ -86,7 +86,7 @@
old_pointer_, size_);
}
-// posix_memalign, memalgin, pvalloc, valloc all recorded with this class.
+// aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
MemalignEntry::MemalignEntry(void* pointer, size_t size, size_t alignment)
: MallocEntry(pointer, size), alignment_(alignment) {
}
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index ccabac2..97ad813 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -129,7 +129,7 @@
DISALLOW_COPY_AND_ASSIGN(ReallocEntry);
};
-// posix_memalign, memalign, pvalloc, valloc all recorded with this class.
+// aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
class MemalignEntry : public MallocEntry {
public:
MemalignEntry(void* pointer, size_t size, size_t alignment);
diff --git a/libc/malloc_debug/exported32.map b/libc/malloc_debug/exported32.map
index e92a7cf..78a6990 100644
--- a/libc/malloc_debug/exported32.map
+++ b/libc/malloc_debug/exported32.map
@@ -1,5 +1,6 @@
LIBC_MALLOC_DEBUG {
global:
+ debug_aligned_alloc;
debug_calloc;
debug_dump_heap;
debug_finalize;
diff --git a/libc/malloc_debug/exported64.map b/libc/malloc_debug/exported64.map
index 94104b0..2bfc38b 100644
--- a/libc/malloc_debug/exported64.map
+++ b/libc/malloc_debug/exported64.map
@@ -1,5 +1,6 @@
LIBC_MALLOC_DEBUG {
global:
+ debug_aligned_alloc;
debug_calloc;
debug_dump_heap;
debug_finalize;
diff --git a/libc/malloc_debug/malloc_debug.cpp b/libc/malloc_debug/malloc_debug.cpp
index a2ada2f..ecfbd71 100644
--- a/libc/malloc_debug/malloc_debug.cpp
+++ b/libc/malloc_debug/malloc_debug.cpp
@@ -77,6 +77,7 @@
size_t debug_malloc_usable_size(void* pointer);
void* debug_malloc(size_t size);
void debug_free(void* pointer);
+void* debug_aligned_alloc(size_t alignment, size_t size);
void* debug_memalign(size_t alignment, size_t bytes);
void* debug_realloc(void* pointer, size_t bytes);
void* debug_calloc(size_t nmemb, size_t bytes);
@@ -669,6 +670,17 @@
return g_dispatch->mallopt(param, value);
}
+void* debug_aligned_alloc(size_t alignment, size_t size) {
+ if (DebugCallsDisabled()) {
+ return g_dispatch->aligned_alloc(alignment, size);
+ }
+ if (!powerof2(alignment)) {
+ errno = EINVAL;
+ return nullptr;
+ }
+ return debug_memalign(alignment, size);
+}
+
int debug_posix_memalign(void** memptr, size_t alignment, size_t size) {
if (DebugCallsDisabled()) {
return g_dispatch->posix_memalign(memptr, alignment, size);
diff --git a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
index 4e90668..0e4a7d8 100644
--- a/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
+++ b/libc/malloc_debug/tests/malloc_debug_unit_tests.cpp
@@ -54,6 +54,7 @@
void* debug_realloc(void*, size_t);
int debug_posix_memalign(void**, size_t, size_t);
void* debug_memalign(size_t, size_t);
+void* debug_aligned_alloc(size_t, size_t);
size_t debug_malloc_usable_size(void*);
void debug_get_malloc_leak_info(uint8_t**, size_t*, size_t*, size_t*, size_t*);
void debug_free_malloc_leak_info(uint8_t*);
@@ -136,6 +137,7 @@
nullptr,
nullptr,
mallopt,
+ aligned_alloc,
};
void VerifyAllocCalls(bool backtrace_enabled) {
@@ -308,6 +310,11 @@
ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
debug_free(pointer);
+ pointer = debug_aligned_alloc(128, 15);
+ ASSERT_TRUE(pointer != nullptr);
+ ASSERT_LE(1039U, debug_malloc_usable_size(pointer));
+ debug_free(pointer);
+
pointer = debug_realloc(nullptr, 30);
ASSERT_TRUE(pointer != nullptr);
ASSERT_LE(1054U, debug_malloc_usable_size(pointer));
@@ -1772,6 +1779,12 @@
debug_free(pointer);
expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
+ pointer = debug_aligned_alloc(32, 50);
+ ASSERT_TRUE(pointer != nullptr);
+ expected += android::base::StringPrintf("%d: memalign %p 32 50\n", getpid(), pointer);
+ debug_free(pointer);
+ expected += android::base::StringPrintf("%d: free %p\n", getpid(), pointer);
+
ASSERT_EQ(0, debug_posix_memalign(&pointer, 32, 50));
ASSERT_TRUE(pointer != nullptr);
expected += android::base::StringPrintf("%d: memalign %p 32 50\n", getpid(), pointer);