6 #ifndef XENIUM_STAMP_IT_HPP
7 #define XENIUM_STAMP_IT_HPP
9 #include <xenium/reclamation/detail/allocation_tracker.hpp>
10 #include <xenium/reclamation/detail/concurrent_ptr.hpp>
11 #include <xenium/reclamation/detail/deletable_object.hpp>
12 #include <xenium/reclamation/detail/guard_ptr.hpp>
13 #include <xenium/reclamation/detail/thread_block_list.hpp>
15 #include <xenium/acquire_guard.hpp>
17 namespace xenium::reclamation {
23 template <
class T,
class MarkedPtr>
27 template <
class T, std::
size_t N = 0,
class Deleter = std::default_delete<T>>
28 class enable_concurrent_ptr;
31 region_guard() noexcept;
34 region_guard(
const region_guard&) =
delete;
35 region_guard(region_guard&&) =
delete;
36 region_guard& operator=(
const region_guard&) =
delete;
37 region_guard& operator=(region_guard&&) =
delete;
40 template <
class T, std::
size_t N = T::number_of_mark_bits>
43 #ifdef WITH_PERF_COUNTER
44 struct performance_counters {
45 size_t push_calls = 0;
46 size_t push_iterations = 0;
47 size_t remove_calls = 0;
48 size_t remove_next_iterations = 0;
49 size_t remove_prev_iterations = 0;
51 static performance_counters get_performance_counters();
57 static constexpr
size_t MarkBits = 18;
59 using stamp_t = size_t;
61 struct deletable_object_with_stamp;
62 struct thread_control_block;
65 class thread_order_queue;
67 static constexpr stamp_t NotInList = 1;
68 static constexpr stamp_t PendingPush = 2;
69 static constexpr stamp_t StampInc = 4;
71 static thread_order_queue queue;
72 static thread_data& local_thread_data();
74 ALLOCATION_TRACKING_FUNCTIONS;
77 struct stamp_it::deletable_object_with_stamp {
78 virtual void delete_self() = 0;
79 deletable_object_with_stamp* next =
nullptr;
80 deletable_object_with_stamp* next_chunk =
nullptr;
83 virtual ~deletable_object_with_stamp() =
default;
87 friend class stamp_it;
90 template <
class T, std::
size_t N,
class Deleter>
91 class stamp_it::enable_concurrent_ptr :
92 private detail::deletable_object_impl<T, Deleter, deletable_object_with_stamp>,
93 private detail::tracked_object<stamp_it> {
95 static constexpr std::size_t number_of_mark_bits = N;
98 enable_concurrent_ptr() noexcept = default;
99 enable_concurrent_ptr(const enable_concurrent_ptr&) noexcept = default;
100 enable_concurrent_ptr(enable_concurrent_ptr&&) noexcept = default;
101 enable_concurrent_ptr& operator=(const enable_concurrent_ptr&) noexcept = default;
102 enable_concurrent_ptr& operator=(enable_concurrent_ptr&&) noexcept = default;
103 ~enable_concurrent_ptr() noexcept override = default;
106 friend detail::deletable_object_impl<T, Deleter, deletable_object_with_stamp>;
108 template <class, class>
109 friend class guard_ptr;
112 template <class T, class MarkedPtr>
113 class stamp_it::guard_ptr : public detail::guard_ptr<T, MarkedPtr, guard_ptr<T, MarkedPtr>> {
114 using base = detail::guard_ptr<T, MarkedPtr, guard_ptr>;
115 using Deleter =
typename T::Deleter;
119 explicit guard_ptr(
const MarkedPtr& p = MarkedPtr()) noexcept;
120 guard_ptr(const guard_ptr& p) noexcept;
121 guard_ptr(guard_ptr&& p) noexcept;
123 guard_ptr& operator=(const guard_ptr& p) noexcept;
124 guard_ptr& operator=(guard_ptr&& p) noexcept;
127 void acquire(const concurrent_ptr<T>& p, std::memory_order order = std::memory_order_seq_cst) noexcept;
130 bool acquire_if_equal(const concurrent_ptr<T>& p,
131 const MarkedPtr& expected,
132 std::memory_order order = std::memory_order_seq_cst) noexcept;
135 void reset() noexcept;
138 void reclaim(Deleter d = Deleter()) noexcept;
142 #define STAMP_IT_IMPL
143 #include <xenium/reclamation/impl/stamp_it.hpp>