From a118c9b7d8fa50a07411e97ac30559e878a24a43 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Thu, 8 Sep 2022 10:40:04 +0100 Subject: [PATCH] Separate locking from static range (#540) Pull a part the locking from the static range. This enables locking to be added to a range directly, and does not require it to be made static. This is useful in cases where the source of memory is shared between threads, but not static. I.e. there are multiple instances of the same type. --- src/snmalloc/backend_helpers/globalrange.h | 35 ++-------------- src/snmalloc/backend_helpers/lockrange.h | 46 ++++++++++++++++++++++ src/snmalloc/backend_helpers/staticrange.h | 42 ++++++++++++++++++++ 3 files changed, 92 insertions(+), 31 deletions(-) create mode 100644 src/snmalloc/backend_helpers/lockrange.h create mode 100644 src/snmalloc/backend_helpers/staticrange.h diff --git a/src/snmalloc/backend_helpers/globalrange.h b/src/snmalloc/backend_helpers/globalrange.h index 760ad21..b6fdbef 100644 --- a/src/snmalloc/backend_helpers/globalrange.h +++ b/src/snmalloc/backend_helpers/globalrange.h @@ -2,6 +2,8 @@ #include "../ds/ds.h" #include "empty_range.h" +#include "lockrange.h" +#include "staticrange.h" namespace snmalloc { @@ -12,36 +14,7 @@ namespace snmalloc struct GlobalRange { template> - class Type : public StaticParent - { - using StaticParent::parent; - - /** - * This is infrequently used code, a spin lock simplifies the code - * considerably, and should never be on the fast path. - */ - SNMALLOC_REQUIRE_CONSTINIT static inline FlagWord spin_lock{}; - - public: - static constexpr bool Aligned = ParentRange::Aligned; - - static constexpr bool ConcurrencySafe = true; - - using ChunkBounds = typename ParentRange::ChunkBounds; - - constexpr Type() = default; - - CapPtr alloc_range(size_t size) - { - FlagLock lock(spin_lock); - return parent.alloc_range(size); - } - - void dealloc_range(CapPtr base, size_t size) - { - FlagLock lock(spin_lock); - parent.dealloc_range(base, size); - } - }; + class Type : public Pipe + {}; }; } // namespace snmalloc diff --git a/src/snmalloc/backend_helpers/lockrange.h b/src/snmalloc/backend_helpers/lockrange.h new file mode 100644 index 0000000..a2b3811 --- /dev/null +++ b/src/snmalloc/backend_helpers/lockrange.h @@ -0,0 +1,46 @@ +#pragma once + +#include "../ds/ds.h" +#include "empty_range.h" + +namespace snmalloc +{ + /** + * Protect the ParentRange with a spin lock. + */ + struct LockRange + { + template> + class Type : public ContainsParent + { + using ContainsParent::parent; + + /** + * This is infrequently used code, a spin lock simplifies the code + * considerably, and should never be on the fast path. + */ + FlagWord spin_lock{}; + + public: + static constexpr bool Aligned = ParentRange::Aligned; + + using ChunkBounds = typename ParentRange::ChunkBounds; + + static constexpr bool ConcurrencySafe = true; + + constexpr Type() = default; + + CapPtr alloc_range(size_t size) + { + FlagLock lock(spin_lock); + return parent.alloc_range(size); + } + + void dealloc_range(CapPtr base, size_t size) + { + FlagLock lock(spin_lock); + parent.dealloc_range(base, size); + } + }; + }; +} // namespace snmalloc diff --git a/src/snmalloc/backend_helpers/staticrange.h b/src/snmalloc/backend_helpers/staticrange.h new file mode 100644 index 0000000..2996c0f --- /dev/null +++ b/src/snmalloc/backend_helpers/staticrange.h @@ -0,0 +1,42 @@ +#pragma once + +#include "../ds/ds.h" +#include "empty_range.h" + +namespace snmalloc +{ + /** + * Makes the supplied ParentRange into a global variable. + */ + struct StaticRange + { + template> + class Type : public StaticParent + { + using StaticParent::parent; + + public: + static constexpr bool Aligned = ParentRange::Aligned; + + static_assert( + ParentRange::ConcurrencySafe, + "StaticRange requires a concurrency safe parent."); + + static constexpr bool ConcurrencySafe = true; + + using ChunkBounds = typename ParentRange::ChunkBounds; + + constexpr Type() = default; + + CapPtr alloc_range(size_t size) + { + return parent.alloc_range(size); + } + + void dealloc_range(CapPtr base, size_t size) + { + parent.dealloc_range(base, size); + } + }; + }; +} // namespace snmalloc