Loading...
// // 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)); 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 __LP64__ && TARGET_OS_OSX T_DECL(posix_memalign_large, "posix_memalign all power of two alignments up to 64GB") { for (size_t alignment = sizeof(void*); alignment <= UINT64_C(68719476736); 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 |