6 #ifndef XENIUM_GENERIC_EPOCH_BASED_HPP
7 #define XENIUM_GENERIC_EPOCH_BASED_HPP
9 #include <xenium/reclamation/detail/concurrent_ptr.hpp>
10 #include <xenium/reclamation/detail/guard_ptr.hpp>
11 #include <xenium/reclamation/detail/deletable_object.hpp>
12 #include <xenium/reclamation/detail/thread_block_list.hpp>
13 #include <xenium/reclamation/detail/retire_list.hpp>
14 #include <xenium/reclamation/detail/allocation_tracker.hpp>
15 #include <xenium/acquire_guard.hpp>
16 #include <xenium/parameter.hpp>
22 namespace reclamation {
52 template <
size_t Threshold>
59 enum class region_extension {
116 template <
class T>
struct scan;
165 namespace reclamation {
167 std::size_t ScanFrequency = 100,
168 class ScanStrategy = scan::all_threads,
169 class AbandonStrategy = abandon::never,
172 struct generic_epoch_based_traits {
174 using scan_strategy = ScanStrategy;
175 using abandon_strategy = AbandonStrategy;
178 template <
class... Policies>
179 using with = generic_epoch_based_traits<
181 parameter::type_param_t<
policy::scan, ScanStrategy, Policies...>,
182 parameter::type_param_t<
policy::abandon, AbandonStrategy, Policies...>,
238 template <
class Traits =
generic_epoch_based_traits<>>
241 template <
class T,
class MarkedPtr>
244 template <
unsigned N>
259 template <
class... Policies>
262 template <
class T, std::
size_t N = 0,
class Deleter = std::default_delete<T>>
263 class enable_concurrent_ptr;
267 region_guard() noexcept;
268 ~region_guard() noexcept;
270 region_guard(const region_guard&) = delete;
271 region_guard(region_guard&&) = delete;
272 region_guard& operator=(const region_guard&) = delete;
273 region_guard& operator=(region_guard&&) = delete;
276 template <class T, std::
size_t N = T::number_of_mark_bits>
281 using epoch_t =
size_t;
283 static constexpr epoch_t number_epochs = 3;
286 struct thread_control_block;
288 inline static std::atomic<epoch_t> global_epoch;
289 inline static detail::thread_block_list<thread_control_block> global_thread_block_list;
290 inline static std::array<detail::orphan_list<>, number_epochs> orphans;
291 inline static thread_local thread_data local_thread_data;
293 ALLOCATION_TRACKING_FUNCTIONS;
296 template <class Traits>
297 template <class T, std::
size_t N, class Deleter>
299 private detail::deletable_object_impl<T, Deleter>,
303 static constexpr std::size_t number_of_mark_bits = N;
305 enable_concurrent_ptr() noexcept = default;
306 enable_concurrent_ptr(const enable_concurrent_ptr&) noexcept = default;
307 enable_concurrent_ptr(enable_concurrent_ptr&&) noexcept = default;
308 enable_concurrent_ptr& operator=(const enable_concurrent_ptr&) noexcept = default;
309 enable_concurrent_ptr& operator=(enable_concurrent_ptr&&) noexcept = default;
310 ~enable_concurrent_ptr() noexcept = default;
312 friend detail::deletable_object_impl<T, Deleter>;
314 template <class, class>
315 friend class guard_ptr;
318 template <class Traits>
319 template <class T, class MarkedPtr>
320 class
generic_epoch_based<Traits>::guard_ptr : public detail::guard_ptr<T, MarkedPtr, guard_ptr<T, MarkedPtr>>
322 using base = detail::guard_ptr<T, MarkedPtr, guard_ptr>;
323 using Deleter =
typename T::Deleter;
326 explicit guard_ptr(
const MarkedPtr& p = MarkedPtr()) noexcept;
327 guard_ptr(const guard_ptr& p) noexcept;
328 guard_ptr(guard_ptr&& p) noexcept;
330 guard_ptr& operator=(const guard_ptr& p) noexcept;
331 guard_ptr& operator=(guard_ptr&& p) noexcept;
334 void acquire(const
concurrent_ptr<T>& p, std::memory_order order = std::memory_order_seq_cst) noexcept;
338 const MarkedPtr& expected,
339 std::memory_order order = std::memory_order_seq_cst) noexcept;
342 void reset() noexcept;
345 void reclaim(Deleter d = Deleter()) noexcept;
349 #define GENERIC_EPOCH_BASED_IMPL
350 #include "impl/generic_epoch_based.hpp"
351 #undef GENERIC_EPOCH_BASED_IMPL
353 namespace xenium {
namespace reclamation {
354 template <
class... Policies>
362 template <
class... Policies>
370 template <
class... Policies>
T must be derived from enable_concurrent_ptr<T>. D is a deleter.
Definition: concurrent_ptr.hpp:21
A generalized implementation of epoch based reclamation.
Definition: generic_epoch_based.hpp:240
Policy to configure the abandon strategy for generic_epoch_based reclamation.
Definition: generic_epoch_based.hpp:139
Policy to configure the extension of critical regions in generic_epoch_based reclamation.
Definition: generic_epoch_based.hpp:162
Policy to configure the scan frequency for generic_epoch_based reclamation.
Definition: generic_epoch_based.hpp:96
Policy to configure the scan strategy for generic_epoch_based reclamation.
Definition: generic_epoch_based.hpp:116
Always abandon the remaining retired nodes when the thread leaves its critical region.
Definition: generic_epoch_based.hpp:99
Never abandon any nodes (except when the thread terminates).
Definition: generic_epoch_based.hpp:90
Abandon the retired nodes upon leaving the critical region when the number of nodes exceeds the speci...
Definition: generic_epoch_based.hpp:113
Scan all threads (default behaviour in EBR/NEBR).
Definition: generic_epoch_based.hpp:23
Scan N threads.
Definition: generic_epoch_based.hpp:49
Scan a single thread (default behaviour in DEBRA).
Definition: generic_epoch_based.hpp:80