6 #ifndef XENIUM_GENERIC_EPOCH_BASED_HPP
7 #define XENIUM_GENERIC_EPOCH_BASED_HPP
9 #include <xenium/acquire_guard.hpp>
10 #include <xenium/parameter.hpp>
11 #include <xenium/reclamation/detail/allocation_tracker.hpp>
12 #include <xenium/reclamation/detail/concurrent_ptr.hpp>
13 #include <xenium/reclamation/detail/deletable_object.hpp>
14 #include <xenium/reclamation/detail/guard_ptr.hpp>
15 #include <xenium/reclamation/detail/retire_list.hpp>
16 #include <xenium/reclamation/detail/thread_block_list.hpp>
22 namespace reclamation {
52 template <
size_t Threshold>
59 enum class region_extension {
96 template <std::
size_t Value>
165 template <reclamation::region_extension Value>
169 namespace reclamation {
170 template <std::size_t ScanFrequency = 100,
171 class ScanStrategy = scan::all_threads,
172 class AbandonStrategy = abandon::never,
174 struct generic_epoch_based_traits {
176 using scan_strategy = ScanStrategy;
177 using abandon_strategy = AbandonStrategy;
180 template <
class... Policies>
181 using with = generic_epoch_based_traits<
183 parameter::type_param_t<
policy::scan, ScanStrategy, Policies...>,
184 parameter::type_param_t<
policy::abandon, AbandonStrategy, Policies...>,
239 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;
265 struct region_guard {
266 region_guard() noexcept;
267 ~region_guard() noexcept;
269 region_guard(const region_guard&) = delete;
270 region_guard(region_guard&&) = delete;
271 region_guard& operator=(const region_guard&) = delete;
272 region_guard& operator=(region_guard&&) = delete;
275 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>,
302 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 override = default;
313 friend detail::deletable_object_impl<T, Deleter>;
315 template <class, class>
316 friend class guard_ptr;
319 template <class Traits>
320 template <class T, class MarkedPtr>
321 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;
327 explicit guard_ptr(
const MarkedPtr& p = MarkedPtr()) noexcept;
328 guard_ptr(const guard_ptr& p) noexcept;
329 guard_ptr(guard_ptr&& p) noexcept;
331 guard_ptr& operator=(const guard_ptr& p) noexcept;
332 guard_ptr& operator=(guard_ptr&& p) noexcept;
335 void acquire(const
concurrent_ptr<T>& p, std::memory_order order = std::memory_order_seq_cst) noexcept;
339 const MarkedPtr& expected,
340 std::memory_order order = std::memory_order_seq_cst) noexcept;
343 void reset() noexcept;
346 void reclaim(Deleter d = Deleter()) noexcept;
351 #define GENERIC_EPOCH_BASED_IMPL
352 #include "impl/generic_epoch_based.hpp"
353 #undef GENERIC_EPOCH_BASED_IMPL
355 namespace xenium::reclamation {
356 template <
class... Policies>
362 template <
class... Policies>
368 template <
class... Policies>