diff --git a/src/mem/alloc.h b/src/mem/alloc.h index ac98224..b56d4b8 100644 --- a/src/mem/alloc.h +++ b/src/mem/alloc.h @@ -1004,7 +1004,7 @@ namespace snmalloc static_assert( std::remove_reference_t::supports_low_memory_notification, + .memory_provider)>::pal_supports(), "A lazy decommit strategy cannot be implemented on platforms " "without low memory notifications"); } diff --git a/src/mem/largealloc.h b/src/mem/largealloc.h index 62de9a6..1be0662 100644 --- a/src/mem/largealloc.h +++ b/src/mem/largealloc.h @@ -47,7 +47,6 @@ namespace snmalloc template class MemoryProviderStateMixin : public PAL { - using PAL::supports_low_memory_notification; std::atomic_flag lock = ATOMIC_FLAG_INIT; size_t bump; size_t remaining; @@ -117,13 +116,21 @@ namespace snmalloc lazy_decommit_guard.clear(); } + public: + template + constexpr static bool pal_supports() + { + return (P::pal_features & F) == F; + } + + private: /** * Wrapper that is instantiated only if the memory provider supports low * memory notifications and forwards the call to the memory provider. */ template ALWAYSINLINE uint64_t low_mem_epoch( - std::enable_if_t = 0) + std::enable_if_t(), int> = 0) { return PAL::low_memory_epoch(); } @@ -135,7 +142,7 @@ namespace snmalloc */ template ALWAYSINLINE uint64_t low_memory_epoch( - std::enable_if_t = 0) + std::enable_if_t(), int> = 0) { return 0; } diff --git a/src/pal/pal.h b/src/pal/pal.h index 7b20d96..9136d89 100644 --- a/src/pal/pal.h +++ b/src/pal/pal.h @@ -3,6 +3,23 @@ namespace snmalloc { void error(const char* const str); + + /** + * Flags in a bitfield of optional features that a PAL may support. These + * should be set in the PAL's `pal_features` static constexpr field. + */ + enum PalFeatures : uint64_t + { + /** + * This PAL supports low memory notifications. It must implement a + * `low_memory_epoch` method that returns a `uint64_t` of the number of + * times that a low-memory notification has been raised and an + * `expensive_low_memory_check()` method that returns a `bool` indicating + * whether low memory conditions are still in effect. + */ + LowMemoryNotification = (1 << 0) + }; + } // If simultating OE, then we need the underlying platform diff --git a/src/pal/pal_free_bsd_kernel.h b/src/pal/pal_free_bsd_kernel.h index 4cada0a..9a3b991 100644 --- a/src/pal/pal_free_bsd_kernel.h +++ b/src/pal/pal_free_bsd_kernel.h @@ -25,10 +25,10 @@ namespace snmalloc public: /** - * Flag indicating that this PAL does not support low pressure - * notifications. + * Bitmap of PalFeatures flags indicating the optional features that this + * PAL supports. */ - static constexpr bool supports_low_memory_notification = false; + static constexpr uint64_t pal_features = 0; void error(const char* const str) { panic("snmalloc error: %s", str); diff --git a/src/pal/pal_freebsd.h b/src/pal/pal_freebsd.h index 06e19a5..f5c843c 100644 --- a/src/pal/pal_freebsd.h +++ b/src/pal/pal_freebsd.h @@ -15,10 +15,10 @@ namespace snmalloc { public: /** - * Flag indicating that this PAL does not support low pressure - * notifications. + * Bitmap of PalFeatures flags indicating the optional features that this + * PAL supports. */ - static constexpr bool supports_low_memory_notification = false; + static constexpr uint64_t pal_features = 0; static void error(const char* const str) { puts(str); diff --git a/src/pal/pal_linux.h b/src/pal/pal_linux.h index 8716ff6..ad86ec7 100644 --- a/src/pal/pal_linux.h +++ b/src/pal/pal_linux.h @@ -14,10 +14,10 @@ namespace snmalloc { public: /** - * Flag indicating that this PAL does not support low pressure - * notifications. + * Bitmap of PalFeatures flags indicating the optional features that this + * PAL supports. */ - static constexpr bool supports_low_memory_notification = false; + static constexpr uint64_t pal_features = 0; static void error(const char* const str) { puts(str); diff --git a/src/pal/pal_open_enclave.h b/src/pal/pal_open_enclave.h index a041af3..3f8d9c6 100644 --- a/src/pal/pal_open_enclave.h +++ b/src/pal/pal_open_enclave.h @@ -15,10 +15,10 @@ namespace snmalloc public: /** - * Flag indicating that this PAL does not support low pressure - * notifications. + * Bitmap of PalFeatures flags indicating the optional features that this + * PAL supports. */ - static constexpr bool supports_low_memory_notification = false; + static constexpr uint64_t pal_features = 0; static void error(const char* const str) { UNUSED(str); diff --git a/src/pal/pal_windows.h b/src/pal/pal_windows.h index efc1aca..420f421 100644 --- a/src/pal/pal_windows.h +++ b/src/pal/pal_windows.h @@ -65,9 +65,10 @@ namespace snmalloc } } /** - * Flag indicating that this PAL supports the low pressure notification. + * Bitmap of PalFeatures flags indicating the optional features that this + * PAL supports. This PAL supports low-memory notifications. */ - static constexpr bool supports_low_memory_notification = true; + static constexpr uint64_t pal_features = LowMemoryNotification; /** * Counter values for the number of times that a low-pressure notification * has been delivered. Callers should compare this with a previous value