Loading...
--- /dev/null
+++ libmalloc/libmalloc-474.0.13/tests/posix_memalign_test.c
@@ -0,0 +1,98 @@
+//
+// posix_memalign_test.c
+// libmalloc
+//
+// test allocating and freeing all sizes and alignments
+//
+
+#include <darwintest.h>
+#include <errno.h>
+#include <malloc/malloc.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+T_GLOBAL_META(T_META_RUN_CONCURRENTLY(true), T_META_TAG_XZONE);
+
+static inline void*
+t_posix_memalign(size_t alignment, size_t size, bool scribble)
+{
+ void *ptr = NULL;
+ int result = posix_memalign(&ptr, alignment, size);
+ size_t allocated_size = malloc_size(ptr);
+
+ T_QUIET; T_ASSERT_NOTNULL(ptr, "allocation");
+ T_QUIET; T_ASSERT_EQ((intptr_t)ptr % alignment, 0ul, "pointer should be properly aligned");
+ T_QUIET; T_EXPECT_LE(size, allocated_size, "allocation size");
+
+ if (scribble) {
+ // Scribble memory pointed to by `ptr` to make sure we're not using that
+ // memory for control structures. This also makes sure the memory can be
+ // written to.
+ const uint64_t pat = 0xdeadbeefcafebabeull;
+ memset_pattern8(ptr, &pat, size);
+ }
+ return ptr;
+}
+
+T_DECL(posix_memalign_free, "posix_memalign all power of two alignments <= 4096")
+{
+ for (size_t alignment = sizeof(void*); alignment < 4096; alignment *= 2) {
+ // test several sizes
+ for (size_t size = alignment; size <= 256*alignment; size += 8) {
+ void* ptr = t_posix_memalign(alignment, size, true);
+ free(ptr);
+ }
+ }
+}
+
+T_DECL(posix_memalign_alignment_not_a_power_of_2, "posix_memalign should return EINVAL if alignment is not a power of 2")
+{
+ {
+ void *ptr = NULL;
+ int result = posix_memalign(&ptr, 24, 48); // alignment is even, but not a power of two
+ T_QUIET; T_ASSERT_NULL(ptr, "ptr should be null");
+ T_QUIET; T_ASSERT_EQ(result, EINVAL, "posix_memalign should return EINVAL");
+ }
+
+ {
+ void *ptr = NULL;
+ int result = posix_memalign(&ptr, 23, 46); // alignment is odd, and not a power of two
+ T_QUIET; T_ASSERT_NULL(ptr, "ptr should be null");
+ T_QUIET; T_ASSERT_EQ(result, EINVAL, "posix_memalign should return EINVAL");
+ }
+}
+
+T_DECL(posix_memalign_alignment_not_a_multiple_of_voidstar, "posix_memalign should return EINVAL if alignment is not a multiple of sizeof(void*)")
+{
+ void *ptr = NULL;
+ const size_t alignment = sizeof(void*)+1;
+ int result = posix_memalign(&ptr, alignment, alignment * 2);
+ T_QUIET; T_ASSERT_NULL(ptr, "ptr should be null");
+ T_QUIET; T_ASSERT_EQ(result, EINVAL, "posix_memalign should return EINVAL");
+}
+
+T_DECL(posix_memalign_allocate_size_0, "posix_memalign should return something that can be passed to free() when size is 0")
+{
+ void *ptr = NULL;
+ int result = posix_memalign(&ptr, 8, 0);
+ T_QUIET; T_ASSERT_EQ(result, 0, "posix_memalign should not return an error when asked for size 0");
+ free(ptr);
+}
+
+#if defined(__LP64__) && TARGET_OS_OSX
+T_DECL(posix_memalign_large, "posix_memalign all power of two alignments up to 64GB")
+{
+ uint64_t max_alignment = UINT64_C(68719476736);
+ if (getenv("MallocSecureAllocator")) {
+ max_alignment = 1024 * 1024; // TODO: support for larger alignments
+ }
+ for (size_t alignment = sizeof(void*); alignment <= max_alignment; alignment *= 2) {
+ // don't scribble - we don't want to actually touch that many pages, we just
+ // verify that the allocated pointer looks reasonable
+ void* ptr = t_posix_memalign(alignment, alignment, false);
+ free(ptr);
+ }
+ T_END;
+}
+#endif // __LP64__ && TARGET_OS_OSX