diff --git a/src/pal/pal_posix.h b/src/pal/pal_posix.h index bab9835..03d39cc 100644 --- a/src/pal/pal_posix.h +++ b/src/pal/pal_posix.h @@ -209,23 +209,30 @@ namespace snmalloc */ std::pair reserve_at_least(size_t size) noexcept { + SNMALLOC_ASSERT(size == bits::next_pow2(size)); + // Magic number for over-allocating chosen by the Pal // These should be further refined based on experiments. constexpr size_t min_size = bits::is64() ? bits::one_at_bit(32) : bits::one_at_bit(28); - auto size_request = bits::max(size, min_size); - void* p = mmap( - nullptr, - size_request, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS | DefaultMMAPFlags::flags, - AnonFD::fd, - 0); - if (p == MAP_FAILED) - OS::error("Out of memory"); + for (size_t size_request = bits::max(size, min_size); + size_request >= size; + size_request = size_request / 2) + { + void* p = mmap( + nullptr, + size_request, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS | DefaultMMAPFlags::flags, + AnonFD::fd, + 0); - return {p, size_request}; + if (p != MAP_FAILED) + return {p, size_request}; + } + + OS::error("Out of memory"); } }; } // namespace snmalloc diff --git a/src/pal/pal_windows.h b/src/pal/pal_windows.h index 08e8c17..b4cec09 100644 --- a/src/pal/pal_windows.h +++ b/src/pal/pal_windows.h @@ -218,19 +218,24 @@ namespace snmalloc # else std::pair reserve_at_least(size_t size) noexcept { + SNMALLOC_ASSERT(size == bits::next_pow2(size)); + // Magic number for over-allocating chosen by the Pal // These should be further refined based on experiments. constexpr size_t min_size = bits::is64() ? bits::one_at_bit(32) : bits::one_at_bit(28); - auto size_request = bits::max(size, min_size); - - DWORD flags = MEM_RESERVE; - void* ret = VirtualAlloc(nullptr, size_request, flags, PAGE_READWRITE); - if (ret == nullptr) + for (size_t size_request = bits::max(size, min_size); + size_request >= size; + size_request = size_request / 2) { - error("Failed to allocate memory\n"); + void* ret = + VirtualAlloc(nullptr, size_request, MEM_RESERVE, PAGE_READWRITE); + if (ret != nullptr) + { + return std::pair(ret, size_request); + } } - return std::pair(ret, size_request); + error("Failed to allocate memory\n"); } # endif };