From 61afa77898d233586acf8567fd2dcc24caa611ab Mon Sep 17 00:00:00 2001 From: Theo Butler Date: Sat, 6 Jun 2020 11:52:50 -0400 Subject: [PATCH] Fix sizeclass rounding error --- src/mem/sizeclass.h | 6 +++- src/test/func/malloc/malloc.cc | 57 ++++++++++++++++++++++------------ 2 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/mem/sizeclass.h b/src/mem/sizeclass.h index e5bb6e3f9..801192d83 100644 --- a/src/mem/sizeclass.h +++ b/src/mem/sizeclass.h @@ -188,10 +188,14 @@ namespace snmalloc SNMALLOC_FAST_PATH static size_t round_size(size_t size) { - if (size > size_to_sizeclass(NUM_SIZECLASSES - 1)) + if (size > sizeclass_to_size(NUM_SIZECLASSES - 1)) { return bits::next_pow2(size); } + if (size == 0) + { + size = 1; + } return sizeclass_to_size(size_to_sizeclass(size)); } } // namespace snmalloc diff --git a/src/test/func/malloc/malloc.cc b/src/test/func/malloc/malloc.cc index d648d9593..029428d74 100644 --- a/src/test/func/malloc/malloc.cc +++ b/src/test/func/malloc/malloc.cc @@ -15,22 +15,39 @@ void check_result(size_t size, size_t align, void* p, int err, bool null) { if (p != nullptr) abort(); - } - else - { - auto asize = our_malloc_usable_size(p); - if (asize < size) - { - printf( - "Usable size is %zu, but required to be at least %zu.\n", asize, size); - abort(); - } - - if (static_cast(reinterpret_cast(p) % align) != 0) - abort(); our_free(p); + return; + } + + const auto alloc_size = our_malloc_usable_size(p); + const auto expected_size = round_size(size); + if ((align == 1) && (alloc_size != expected_size)) + { + printf( + "Usable size is %zu, but required to be %zu.\n", + alloc_size, + expected_size); + abort(); + } + if ((align != 1) && (alloc_size < expected_size)) + { + printf( + "Usable size is %zu, but required to be at least %zu.\n", + alloc_size, + expected_size); + abort(); } + if (static_cast(reinterpret_cast(p) % align) != 0) + { + printf( + "Address is 0x%zx, but required to be aligned to 0x%zx.\n", + reinterpret_cast(p), + align); + abort(); + } + + our_free(p); } void test_calloc(size_t nmemb, size_t size, int err, bool null) @@ -92,7 +109,7 @@ int main(int argc, char** argv) test_realloc(our_malloc(64), 4194304, SUCCESS, false); - for (snmalloc::sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++) + for (sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++) { const size_t size = 1ULL << sc; printf("malloc: %zu\n", size); @@ -102,7 +119,7 @@ int main(int argc, char** argv) test_calloc(0, 0, SUCCESS, false); - for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) + for (sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) { const size_t size = sizeclass_to_size(sc); @@ -118,14 +135,14 @@ int main(int argc, char** argv) test_calloc(0, size, SUCCESS, false); } - for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) + for (sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) { const size_t size = sizeclass_to_size(sc); test_realloc(our_malloc(size), size, SUCCESS, false); test_realloc(our_malloc(size), 0, SUCCESS, true); test_realloc(nullptr, size, SUCCESS, false); test_realloc(our_malloc(size), (size_t)-1, ENOMEM, true); - for (snmalloc::sizeclass_t sc2 = 0; sc2 < NUM_SIZECLASSES; sc2++) + for (sizeclass_t sc2 = 0; sc2 < NUM_SIZECLASSES; sc2++) { const size_t size2 = sizeclass_to_size(sc2); test_realloc(our_malloc(size), size2, SUCCESS, false); @@ -133,14 +150,14 @@ int main(int argc, char** argv) } } - for (snmalloc::sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++) + for (sizeclass_t sc = 0; sc < (SUPERSLAB_BITS + 4); sc++) { const size_t size = 1ULL << sc; test_realloc(our_malloc(size), size, SUCCESS, false); test_realloc(our_malloc(size), 0, SUCCESS, true); test_realloc(nullptr, size, SUCCESS, false); test_realloc(our_malloc(size), (size_t)-1, ENOMEM, true); - for (snmalloc::sizeclass_t sc2 = 0; sc2 < (SUPERSLAB_BITS + 4); sc2++) + for (sizeclass_t sc2 = 0; sc2 < (SUPERSLAB_BITS + 4); sc2++) { const size_t size2 = 1ULL << sc2; printf("size1: %zu, size2:%zu\n", size, size2); @@ -156,7 +173,7 @@ int main(int argc, char** argv) for (size_t align = sizeof(uintptr_t); align <= SUPERSLAB_SIZE * 8; align <<= 1) { - for (snmalloc::sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) + for (sizeclass_t sc = 0; sc < NUM_SIZECLASSES; sc++) { const size_t size = sizeclass_to_size(sc); test_posix_memalign(size, align, SUCCESS, false);