#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 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 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 void zero(void* p, size_t size) noexcept { oe_memset(p, 0, size); } }; } #endif