The PAL can now advertise that it supports aligned allocation. If it does not, then the memory provider will do the alignment for it. This change still leaves the PAL responsible for systematic testing, but it should now be much easier to lift that out.
64 lines
1.5 KiB
C++
64 lines
1.5 KiB
C++
#pragma once
|
|
|
|
#include "pal_plain.h"
|
|
#ifdef OPEN_ENCLAVE
|
|
extern "C" const void* __oe_get_heap_base();
|
|
extern "C" const void* __oe_get_heap_end();
|
|
extern "C" void* oe_memset(void* p, int c, size_t size);
|
|
extern "C" void oe_abort();
|
|
|
|
namespace snmalloc
|
|
{
|
|
class PALOpenEnclave
|
|
{
|
|
std::atomic<uintptr_t> oe_base;
|
|
|
|
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)
|
|
{
|
|
UNUSED(str);
|
|
oe_abort();
|
|
}
|
|
|
|
template<bool committed>
|
|
void* reserve(size_t* size, size_t align) noexcept
|
|
{
|
|
if (oe_base == 0)
|
|
{
|
|
uintptr_t dummy = 0;
|
|
oe_base.compare_exchange_strong(dummy, (uintptr_t)__oe_get_heap_base());
|
|
}
|
|
|
|
uintptr_t old_base = oe_base;
|
|
uintptr_t old_base2 = old_base;
|
|
uintptr_t next_base;
|
|
auto end = (uintptr_t)__oe_get_heap_end();
|
|
do
|
|
{
|
|
old_base2 = old_base;
|
|
auto new_base = bits::align_up(old_base, align);
|
|
next_base = new_base + *size;
|
|
|
|
if (next_base > end)
|
|
error("Out of memory");
|
|
|
|
} while (oe_base.compare_exchange_strong(old_base, next_base));
|
|
|
|
*size = next_base - old_base2;
|
|
return (void*)old_base;
|
|
}
|
|
|
|
template<bool page_aligned = false>
|
|
void zero(void* p, size_t size) noexcept
|
|
{
|
|
oe_memset(p, 0, size);
|
|
}
|
|
};
|
|
}
|
|
#endif
|