- CI merge issues:
- The malloc shim libraries are renamed.
- CMake gets very unhappy if you don't enable the C language and
tries to link with the C compiler instead of the C++ compiler if
you do enable it.
- The Ubuntu packages for QEMU install a `binfmt_misc` activator for
PowerPC64 little-endian, but set the page size to 4 KiB. We then
tried to run the tests (which expect 64 KiB pages) and became very
confused when `mmap` returned 4 KiB-aligned memory.
- Test failures:
- Fix all of the issues UBsan found.
- Underflow in `pointer_offset` when used to add negative offsets.
- `CoreAlloc`'s `LocalState` accessed on a null `CoreAlloc` pointer.
- Out of bounds access in the sizeclass list on attempts to access
more memory than fits in the VA space.
-
- There was an integer overflow in `AddressSpace` that could cause it
to try to allocate a zero-sized object, get a null pointer, and
then try to do something with 0 - {size of the real allocation}.
- The malloc tests weren't setting `errno` to 0 before doing
calling `malloc`, which should set `errno` on failure, and then
checking that `errno` was 0.
- Don't call `PAL::error` on PAL allocation failure, return `nullptr`.
The PALs were inconsistent about that and the new code expects to be
able to report address-space exhaustion.
- The malloc checks can behave differently with 0-sized allocations
on different platforms but were very fragile about their
expectations.
- The malloc test didn't report failure for all of the ways that it
could fail and so was spuriously passing on some platforms.
- The perf test for external pointer is currently very slow on
Windows. The number of loops have been reduced and a timeout added
for the Windows CI runs.
- The logic to capture `errno` across calls was using
`decltype(errno)`, which on some platforms where `errno` is a macro
evaluated to `int&` and so they captured a reference rather than
the value and failed to reset `errno`.
- The Apple PAL can set `errno` on `notify_using` if it's called with
memory that was not previously passed to `notify_not_using` but was
not adequately protected against this and so would sometimes cause
`malloc` to set `errno` to `EINVAL`.
61 lines
1.4 KiB
C++
61 lines
1.4 KiB
C++
#pragma once
|
|
|
|
#include "pal_bsd.h"
|
|
|
|
namespace snmalloc
|
|
{
|
|
/**
|
|
* FreeBSD-specific platform abstraction layer.
|
|
*
|
|
* This adds aligned allocation using `MAP_ALIGNED` to the generic BSD
|
|
* implementation. This flag is supported by NetBSD and FreeBSD.
|
|
*/
|
|
template<class OS>
|
|
class PALBSD_Aligned : public PALBSD<OS>
|
|
{
|
|
public:
|
|
/**
|
|
* Bitmap of PalFeatures flags indicating the optional features that this
|
|
* PAL supports.
|
|
*
|
|
* This class adds support for aligned allocation.
|
|
*/
|
|
static constexpr uint64_t pal_features =
|
|
AlignedAllocation | PALBSD<OS>::pal_features;
|
|
|
|
static SNMALLOC_CONSTINIT_STATIC size_t minimum_alloc_size = 4096;
|
|
|
|
/**
|
|
* Reserve memory at a specific alignment.
|
|
*/
|
|
template<bool committed>
|
|
static void* reserve_aligned(size_t size) noexcept
|
|
{
|
|
// Alignment must be a power of 2.
|
|
SNMALLOC_ASSERT(bits::is_pow2(size));
|
|
SNMALLOC_ASSERT(size >= minimum_alloc_size);
|
|
|
|
int log2align = static_cast<int>(bits::next_pow2_bits(size));
|
|
|
|
#ifdef SNMALLOC_CHECK_CLIENT
|
|
auto prot = committed ? PROT_READ | PROT_WRITE : PROT_NONE;
|
|
#else
|
|
auto prot = PROT_READ | PROT_WRITE;
|
|
#endif
|
|
|
|
void* p = mmap(
|
|
nullptr,
|
|
size,
|
|
prot,
|
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED(log2align),
|
|
-1,
|
|
0);
|
|
|
|
if (p == MAP_FAILED)
|
|
return nullptr;
|
|
|
|
return p;
|
|
}
|
|
};
|
|
} // namespace snmalloc
|