This complains if a non-const parameter is not modified. In the PALs, the size parameter is modified only by some implementations, so we can make it const in the ones where it isn't.
96 lines
2.2 KiB
C++
96 lines
2.2 KiB
C++
#pragma once
|
|
|
|
#if defined(__FreeBSD__) && !defined(_KERNEL)
|
|
# include "../ds/bits.h"
|
|
# include "../mem/allocconfig.h"
|
|
|
|
# include <stdio.h>
|
|
# include <strings.h>
|
|
# include <sys/mman.h>
|
|
|
|
namespace snmalloc
|
|
{
|
|
class PALFBSD
|
|
{
|
|
public:
|
|
/**
|
|
* Bitmap of PalFeatures flags indicating the optional features that this
|
|
* PAL supports.
|
|
*/
|
|
static constexpr uint64_t pal_features = AlignedAllocation;
|
|
static void error(const char* const str)
|
|
{
|
|
puts(str);
|
|
abort();
|
|
}
|
|
|
|
/// Notify platform that we will not be using these pages
|
|
void notify_not_using(void* p, size_t size) noexcept
|
|
{
|
|
assert(bits::is_aligned_block<OS_PAGE_SIZE>(p, size));
|
|
madvise(p, size, MADV_FREE);
|
|
}
|
|
|
|
/// Notify platform that we will be using these pages
|
|
template<ZeroMem zero_mem>
|
|
void notify_using(void* p, size_t size) noexcept
|
|
{
|
|
assert(
|
|
bits::is_aligned_block<OS_PAGE_SIZE>(p, size) || (zero_mem == NoZero));
|
|
if constexpr (zero_mem == YesZero)
|
|
zero(p, size);
|
|
}
|
|
|
|
/// OS specific function for zeroing memory
|
|
template<bool page_aligned = false>
|
|
void zero(void* p, size_t size) noexcept
|
|
{
|
|
if (page_aligned || bits::is_aligned_block<OS_PAGE_SIZE>(p, size))
|
|
{
|
|
assert(bits::is_aligned_block<OS_PAGE_SIZE>(p, size));
|
|
void* r = mmap(
|
|
p,
|
|
size,
|
|
PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED,
|
|
-1,
|
|
0);
|
|
|
|
if (r != MAP_FAILED)
|
|
return;
|
|
}
|
|
|
|
bzero(p, size);
|
|
}
|
|
|
|
template<bool committed>
|
|
void* reserve(const size_t* size, size_t align) noexcept
|
|
{
|
|
size_t request = *size;
|
|
// Alignment must be a power of 2.
|
|
assert(align == bits::next_pow2(align));
|
|
|
|
if (align == 0)
|
|
{
|
|
align = 1;
|
|
}
|
|
|
|
size_t log2align = bits::next_pow2_bits(align);
|
|
|
|
void* p = mmap(
|
|
nullptr,
|
|
request,
|
|
PROT_READ | PROT_WRITE,
|
|
MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED(log2align),
|
|
-1,
|
|
0);
|
|
|
|
if (p == MAP_FAILED)
|
|
error("Out of memory");
|
|
|
|
return p;
|
|
}
|
|
};
|
|
} // namespace snmalloc
|
|
#endif
|