diff --git a/src/pal/pal.h b/src/pal/pal.h index e9170251..896d957f 100644 --- a/src/pal/pal.h +++ b/src/pal/pal.h @@ -33,6 +33,7 @@ namespace snmalloc // If simultating OE, then we need the underlying platform #if !defined(OPEN_ENCLAVE) || defined(OPEN_ENCLAVE_SIMULATION) +# include "pal_apple.h" # include "pal_free_bsd_kernel.h" # include "pal_freebsd.h" # include "pal_linux.h" @@ -47,6 +48,8 @@ namespace snmalloc using DefaultPal = # if defined(_WIN32) PALWindows; +# elif defined(__APPLE__) + PALApple; # elif defined(__linux__) PALLinux; # elif defined(FreeBSD_KERNEL) diff --git a/src/pal/pal_apple.h b/src/pal/pal_apple.h new file mode 100644 index 00000000..4c5e643b --- /dev/null +++ b/src/pal/pal_apple.h @@ -0,0 +1,88 @@ +#pragma once + +#ifdef __APPLE__ +# include "../ds/bits.h" +# include "../mem/allocconfig.h" + +# include +# include +# include +# include + +namespace snmalloc +{ + /** + * PAL implementation for Apple systems (macOS, iOS, watchOS, tvOS...). + */ + class PALApple + { + public: + /** + * Bitmap of PalFeatures flags indicating the optional features that this + * PAL supports. + */ + static constexpr uint64_t pal_features = 0; + 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(p, size)); + madvise(p, size, MADV_FREE); + } + + /// Notify platform that we will be using these pages + template + void notify_using(void* p, size_t size) noexcept + { + assert( + bits::is_aligned_block(p, size) || (zero_mem == NoZero)); + if constexpr (zero_mem == YesZero) + zero(p, size); + } + + /// OS specific function for zeroing memory + template + void zero(void* p, size_t size) noexcept + { + if (page_aligned || bits::is_aligned_block(p, size)) + { + assert(bits::is_aligned_block(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 + void* reserve(size_t* size) noexcept + { + void* p = mmap( + NULL, + *size, + PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, + -1, + 0); + + if (p == MAP_FAILED) + error("Out of memory"); + + return p; + } + }; +} +#endif