xenium
quiescent_state_based.hpp
1 //
2 // Copyright (c) 2018-2020 Manuel Pöter.
3 // Licensed under the MIT License. See LICENSE file in the project root for full license information.
4 //
5 
6 #ifndef XENIUM_QUIESCENT_STATE_BASED_HPP
7 #define XENIUM_QUIESCENT_STATE_BASED_HPP
8 
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>
14 
15 #include <xenium/acquire_guard.hpp>
16 
17 namespace xenium::reclamation {
18 
23  template <class T, class MarkedPtr>
24  class guard_ptr;
25 
26 public:
27  template <class T, std::size_t N = 0, class Deleter = std::default_delete<T>>
28  class enable_concurrent_ptr;
29 
30  struct region_guard {
31  region_guard() noexcept;
32  ~region_guard() noexcept;
33 
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;
38  };
39 
40  template <class T, std::size_t N = T::number_of_mark_bits>
42 
43  ALLOCATION_TRACKER;
44 
45 private:
46  static constexpr unsigned number_epochs = 3;
47 
48  struct thread_data;
49  struct thread_control_block;
50 
51  inline static std::atomic<unsigned> global_epoch;
52  inline static detail::thread_block_list<thread_control_block> global_thread_block_list;
53  static thread_data& local_thread_data();
54 
55  ALLOCATION_TRACKING_FUNCTIONS;
56 };
57 
58 template <class T, std::size_t N, class Deleter>
59 class quiescent_state_based::enable_concurrent_ptr :
60  private detail::deletable_object_impl<T, Deleter>,
61  private detail::tracked_object<quiescent_state_based> {
62 public:
63  static constexpr std::size_t number_of_mark_bits = N;
64 
65 protected:
66  enable_concurrent_ptr() noexcept = default;
67  enable_concurrent_ptr(const enable_concurrent_ptr&) noexcept = default;
68  enable_concurrent_ptr(enable_concurrent_ptr&&) noexcept = default;
69  enable_concurrent_ptr& operator=(const enable_concurrent_ptr&) noexcept = default;
70  enable_concurrent_ptr& operator=(enable_concurrent_ptr&&) noexcept = default;
71  ~enable_concurrent_ptr() noexcept override = default;
72 
73 private:
74  friend detail::deletable_object_impl<T, Deleter>;
75 
76  template <class, class>
77  friend class guard_ptr;
78 };
79 
80 template <class T, class MarkedPtr>
81 class quiescent_state_based::guard_ptr : public detail::guard_ptr<T, MarkedPtr, guard_ptr<T, MarkedPtr>> {
82  using base = detail::guard_ptr<T, MarkedPtr, guard_ptr>;
83  using Deleter = typename T::Deleter;
84 
85 public:
86  // Guard a marked ptr.
87  explicit guard_ptr(const MarkedPtr& p = MarkedPtr()) noexcept;
88  guard_ptr(const guard_ptr& p) noexcept;
89  guard_ptr(guard_ptr&& p) noexcept;
90 
91  guard_ptr& operator=(const guard_ptr& p) noexcept;
92  guard_ptr& operator=(guard_ptr&& p) noexcept;
93 
94  // Atomically take snapshot of p, and *if* it points to unreclaimed object, acquire shared ownership of it.
95  void acquire(const concurrent_ptr<T>& p, std::memory_order order = std::memory_order_seq_cst) noexcept;
96 
97  // Like acquire, but quit early if a snapshot != expected.
98  bool acquire_if_equal(const concurrent_ptr<T>& p,
99  const MarkedPtr& expected,
100  std::memory_order order = std::memory_order_seq_cst) noexcept;
101 
102  // Release ownership. Postcondition: get() == nullptr.
103  void reset() noexcept;
104 
105  // Reset. Deleter d will be applied some time after all owners release their ownership.
106  void reclaim(Deleter d = Deleter()) noexcept;
107 };
108 } // namespace xenium::reclamation
109 
110 #define QUIESCENT_STATE_BASED_IMPL
111 #include <xenium/reclamation/impl/quiescent_state_based.hpp>
112 #undef QUIESCENT_STATE_BASED_IMPL
113 
114 #endif
xenium::reclamation::detail::concurrent_ptr
T must be derived from enable_concurrent_ptr<T>. D is a deleter.
Definition: concurrent_ptr.hpp:17
xenium::reclamation::quiescent_state_based
Quiescent state based reclamation.
Definition: quiescent_state_based.hpp:22