diff --git a/src/test/func/malloc/malloc.cc b/src/test/func/malloc/malloc.cc index 8c08b9e..54db607 100644 --- a/src/test/func/malloc/malloc.cc +++ b/src/test/func/malloc/malloc.cc @@ -1,35 +1,12 @@ #include #include -#include #include #include -#include using namespace snmalloc; -constexpr size_t min_pow_2 = bits::ctz_const(sizeof(size_t)); -constexpr size_t max_pow_2 = bits::ctz_const(SUPERSLAB_SIZE); - -size_t rand_pow_2(xoroshiro::p128r64& r, size_t min_pow = min_pow_2) -{ - const size_t max_pow = max_pow_2 - min_pow; - auto p = (r.next() % (max_pow + 1)) + min_pow; - return (size_t)1 << p; -} - -size_t rand_non_pow_2(xoroshiro::p128r64& r, size_t min = 0) -{ - const size_t max = (1 << max_pow_2) - min; - auto n = (r.next() % (max + 1)) + min; - while (__builtin_popcount(n) < 2) - n = r.next(); - - return n; -} - void check_result(size_t size, void* p, int err, bool null) { - fprintf(stderr, "%p, errno: %s\n", p, strerror(errno)); // TODO assert(errno == err); UNUSED(err); if (null) @@ -59,7 +36,7 @@ void test_calloc(size_t nmemb, size_t size, int err, bool null) void test_realloc(void* p, size_t size, int err, bool null) { - fprintf(stderr, "realloc(%p, %d)\n", p, (int)size); + fprintf(stderr, "realloc(%p (%d), %d)\n", p, int(size), (int)size); errno = 0; p = realloc(p, size); check_result(size, p, err, null); @@ -92,36 +69,42 @@ int main(int argc, char** argv) constexpr int SUCCESS = 0; - auto r = xoroshiro::p128r64((size_t)time(nullptr)); - - size_t n, s; - do + for (uint8_t sc = 0; sc < NUM_SIZECLASSES; sc++) { - n = rand_pow_2(r); - s = rand_pow_2(r); - } while ((n * s) > (1 << max_pow_2)); - test_calloc(n, s, SUCCESS, false); - test_calloc(0, 0, SUCCESS, false); - test_calloc((size_t)-1, 1, ENOMEM, true); + const size_t size = sizeclass_to_size(sc); - test_realloc(malloc(rand_pow_2(r)), 0, SUCCESS, true); - test_realloc(nullptr, rand_pow_2(r), SUCCESS, false); - test_realloc(malloc(rand_pow_2(r)), (size_t)-1, ENOMEM, true); + test_calloc(0, 0, SUCCESS, false); + test_calloc((size_t)-1, 1, ENOMEM, true); + + 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_realloc(malloc(size), 0, SUCCESS, true); + test_realloc(nullptr, size, SUCCESS, false); + test_realloc(malloc(size), (size_t)-1, ENOMEM, true); + } - test_posix_memalign(rand_pow_2(r), rand_pow_2(r), SUCCESS, false); test_posix_memalign(0, 0, EINVAL, true); - test_posix_memalign(0, rand_pow_2(r), SUCCESS, false); test_posix_memalign((size_t)-1, 0, EINVAL, true); - test_posix_memalign(0, rand_non_pow_2(r), EINVAL, true); - test_posix_memalign((size_t)-1, rand_pow_2(r), ENOMEM, true); - test_memalign(rand_pow_2(r), rand_pow_2(r), SUCCESS, false); - - // snmalloc and glibc pass, not jemalloc - test_memalign((size_t)-1, rand_pow_2(r), ENOMEM, true); - - // glibc passes, not snmalloc or jemalloc - // test_memalign((size_t)-1, 0, ENOMEM, 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_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; }