diff --git a/CMakeLists.txt b/CMakeLists.txt index 2bfc4ecc7..61359b76c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -76,11 +76,18 @@ subdirlist(TEST_CATEGORIES ${TESTDIR}) foreach(SUPER_SLAB_SIZE 1;16) foreach(TEST_CATEGORY ${TEST_CATEGORIES}) subdirlist(TESTS ${TESTDIR}/${TEST_CATEGORY}) + if(MSVC) + list(REMOVE_ITEM TESTS "malloc") + endif() foreach(TEST ${TESTS}) unset(SRC) aux_source_directory(${TESTDIR}/${TEST_CATEGORY}/${TEST} SRC) set(TESTNAME "${TEST_CATEGORY}-${TEST}-${SUPER_SLAB_SIZE}") - add_executable(${TESTNAME} ${SRC} src/override/new.cc) + if(${TEST} STREQUAL "malloc") + add_executable(${TESTNAME} ${SRC} src/override/malloc.cc) + else() + add_executable(${TESTNAME} ${SRC} src/override/new.cc) + endif() if (${SUPER_SLAB_SIZE} EQUAL 1) target_compile_definitions(${TESTNAME} PRIVATE IS_ADDRESS_SPACE_CONSTRAINED) endif() diff --git a/src/override/malloc.cc b/src/override/malloc.cc index 218191e58..7c704d46c 100644 --- a/src/override/malloc.cc +++ b/src/override/malloc.cc @@ -43,7 +43,7 @@ extern "C" if (overflow) { errno = ENOMEM; - return 0; + return nullptr; } // Include size 0 in the first sizeclass. sz = ((sz - 1) >> (bits::BITS - 1)) + sz; @@ -135,7 +135,8 @@ extern "C" return nullptr; } - uint8_t sc = size_to_sizeclass((std::max)(size, alignment)); + size = (std::max)(size, alignment); + uint8_t sc = size_to_sizeclass(size); if (sc >= NUM_SIZECLASSES) { // large allocs are 16M aligned. @@ -149,8 +150,7 @@ extern "C" return SNMALLOC_NAME_MANGLE(aligned_alloc)(alignment, size); } } - assert(false); - return nullptr; + return SNMALLOC_NAME_MANGLE(malloc)(SUPERSLAB_SIZE); } SNMALLOC_EXPORT int SNMALLOC_NAME_MANGLE(posix_memalign)( diff --git a/src/pal/pal_free_bsd_kernel.h b/src/pal/pal_free_bsd_kernel.h index 1ae5d2c5d..184e854ee 100644 --- a/src/pal/pal_free_bsd_kernel.h +++ b/src/pal/pal_free_bsd_kernel.h @@ -36,7 +36,7 @@ namespace snmalloc kmem_unback(kernel_object, addr, size); } - /// Notify platform that we will not be using these pages + /// Notify platform that we will be using these pages template void notify_using(void* p, size_t size) { diff --git a/src/pal/pal_freebsd.h b/src/pal/pal_freebsd.h index 90a2f5b7a..4b1e856fe 100644 --- a/src/pal/pal_freebsd.h +++ b/src/pal/pal_freebsd.h @@ -27,7 +27,7 @@ namespace snmalloc madvise(p, size, MADV_FREE); } - /// Notify platform that we will not be using these pages + /// Notify platform that we will be using these pages template void notify_using(void* p, size_t size) noexcept { diff --git a/src/pal/pal_linux.h b/src/pal/pal_linux.h index 711d77428..fb0605807 100644 --- a/src/pal/pal_linux.h +++ b/src/pal/pal_linux.h @@ -29,7 +29,7 @@ namespace snmalloc UNUSED(size); } - /// Notify platform that we will not be using these pages + /// Notify platform that we will be using these pages template void notify_using(void* p, size_t size) noexcept { diff --git a/src/pal/pal_windows.h b/src/pal/pal_windows.h index 7fcd00ec1..82b6b6cf1 100644 --- a/src/pal/pal_windows.h +++ b/src/pal/pal_windows.h @@ -30,7 +30,7 @@ namespace snmalloc error("VirtualFree failed"); } - /// Notify platform that we will not be using these pages + /// Notify platform that we will be using these pages template void notify_using(void* p, size_t size) noexcept { @@ -108,4 +108,4 @@ namespace snmalloc } }; } -#endif \ No newline at end of file +#endif diff --git a/src/test/func/malloc/malloc.cc b/src/test/func/malloc/malloc.cc new file mode 100644 index 000000000..7cb02a384 --- /dev/null +++ b/src/test/func/malloc/malloc.cc @@ -0,0 +1,118 @@ +#include +#include +#include + +using namespace snmalloc; + +void check_result(size_t size, size_t align, void* p, int err, bool null) +{ + if (errno != err) + abort(); + + if (null) + { + if (p != nullptr) + abort(); + } + else + { + if (malloc_usable_size(p) < size) + abort(); + + if (((uintptr_t)p % align) != 0) + abort(); + + free(p); + } +} + +void test_calloc(size_t nmemb, size_t size, int err, bool null) +{ + fprintf(stderr, "calloc(%d, %d)\n", (int)nmemb, (int)size); + errno = 0; + void* p = calloc(nmemb, size); + + if ((p != nullptr) && (errno == 0)) + { + for (size_t i = 0; i < (size * nmemb); i++) + { + if (((uint8_t*)p)[i] != 0) + abort(); + } + } + check_result(nmemb * size, 1, p, err, null); +} + +void test_realloc(void* p, size_t size, int err, bool null) +{ + fprintf(stderr, "realloc(%p(%d), %d)\n", p, int(size), (int)size); + errno = 0; + p = realloc(p, size); + check_result(size, 1, p, err, null); +} + +void test_posix_memalign(size_t size, size_t align, int err, bool null) +{ + fprintf(stderr, "posix_memalign(&p, %d, %d)\n", (int)align, (int)size); + void* p = nullptr; + errno = posix_memalign(&p, align, size); + check_result(size, align, p, err, null); +} + +void test_memalign(size_t size, size_t align, int err, bool null) +{ + fprintf(stderr, "memalign(%d, %d)\n", (int)align, (int)size); + errno = 0; + void* p = memalign(align, size); + check_result(size, align, p, err, null); +} + +int main(int argc, char** argv) +{ + UNUSED(argc); + UNUSED(argv); + + constexpr int SUCCESS = 0; + + test_calloc(0, 0, SUCCESS, false); + + for (uint8_t sc = 0; sc < NUM_SIZECLASSES; sc++) + { + const size_t size = sizeclass_to_size(sc); + + bool overflow = false; + for (size_t n = 1; bits::umul(size, n, overflow) <= SUPERSLAB_SIZE; n *= 5) + { + if (overflow) + break; + + test_calloc(n, size, SUCCESS, false); + test_calloc(n, 0, SUCCESS, false); + } + test_calloc(0, size, SUCCESS, false); + + test_realloc(malloc(size), size, SUCCESS, false); + test_realloc(malloc(size), 0, SUCCESS, true); + test_realloc(nullptr, size, SUCCESS, false); + test_realloc(malloc(size), (size_t)-1, ENOMEM, true); + } + + test_posix_memalign(0, 0, EINVAL, true); + test_posix_memalign((size_t)-1, 0, EINVAL, true); + + for (size_t align = sizeof(size_t); align <= SUPERSLAB_SIZE; align <<= 1) + { + for (uint8_t sc = 0; sc < NUM_SIZECLASSES; sc++) + { + const size_t size = sizeclass_to_size(sc); + test_posix_memalign(size, align, SUCCESS, false); + test_posix_memalign(size, 0, EINVAL, true); + test_memalign(size, align, SUCCESS, false); + } + test_posix_memalign(0, align, SUCCESS, false); + test_posix_memalign((size_t)-1, align, ENOMEM, true); + test_posix_memalign(0, align + 1, EINVAL, true); + } + + return 0; +} diff --git a/src/test/func/rounding/rounding.cc b/src/test/func/rounding/rounding.cc index e15cfd6fe..8c3a9e8b7 100644 --- a/src/test/func/rounding/rounding.cc +++ b/src/test/func/rounding/rounding.cc @@ -1,7 +1,4 @@ #include -#include -#include -#include using namespace snmalloc;