Expose reserve_at_least in all Pals

This commit is contained in:
Matthew Parkinson
2021-07-16 09:41:58 +01:00
committed by Matthew Parkinson
parent 2ba0de76b3
commit 8b1ffbc166
3 changed files with 7 additions and 49 deletions

View File

@@ -49,9 +49,10 @@ template<bool committed>
static void* reserve_aligned(size_t size) noexcept;
static std::pair<void*, size_t> reserve_at_least(size_t size) noexcept;
```
Only one of these needs to be implemented, depending on whether the underlying
system can provide strongly aligned memory regions.
If the system guarantees only page alignment, implement the second. The Pal is
All platforms should provide `reserve_at_least` and can optionally provide
`reserve_aligned` if the underlying system can provide strongly aligned
memory regions.
If the system guarantees only page alignment, implement only the second. The Pal is
free to overallocate based on the platform's desire and snmalloc
will find suitably aligned blocks inside the region. `reserve_at_least` should
not commit memory as snmalloc will commit the range of memory it requires of what

View File

@@ -50,17 +50,5 @@ namespace snmalloc
return p;
}
/**
* Explicitly deleted method for returning non-aligned memory. This causes
* incorrect use of `constexpr if` to fail on platforms with aligned
* allocation. Without this, this PAL and its subclasses exported both
* allocation functions and so callers would type-check if they called
* either in `constexpr if` branches and then fail on platforms such as
* Linux or Windows, which expose only unaligned or aligned allocations,
* respectively.
*/
static std::pair<void*, size_t>
reserve_at_least(size_t size) noexcept = delete;
};
} // namespace snmalloc

View File

@@ -152,38 +152,7 @@ namespace snmalloc
::memset(p, 0, size);
}
# ifdef USE_SYSTEMATIC_TESTING
static size_t& systematic_bump_ptr()
{
static size_t bump_ptr = (size_t)0x4000'0000'0000;
return bump_ptr;
}
static std::pair<void*, size_t> reserve_at_least(size_t size) noexcept
{
// 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;
size_t retries = 1000;
void* p;
do
{
p = VirtualAlloc(
(void*)systematic_bump_ptr(), size_request, flags, PAGE_READWRITE);
systematic_bump_ptr() += size_request;
retries--;
} while (p == nullptr && retries > 0);
return {p, size_request};
}
# elif defined(PLATFORM_HAS_VIRTUALALLOC2)
# ifdef PLATFORM_HAS_VIRTUALALLOC2
template<bool committed>
static void* reserve_aligned(size_t size) noexcept
{
@@ -214,7 +183,8 @@ namespace snmalloc
}
return ret;
}
# else
# endif
static std::pair<void*, size_t> reserve_at_least(size_t size) noexcept
{
SNMALLOC_ASSERT(bits::is_pow2(size));
@@ -236,7 +206,6 @@ namespace snmalloc
}
error("Failed to allocate memory\n");
}
# endif
/**
* Source of Entropy