xenium
concurrent_ptr.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_DETAL_CONCURRENT_PTR_HPP
7 #define XENIUM_DETAL_CONCURRENT_PTR_HPP
8 
9 #include <xenium/marked_ptr.hpp>
10 
11 #include <atomic>
12 
13 namespace xenium::reclamation::detail {
14 
16 template <class T, std::size_t N, template <class, class MarkedPtr> class GuardPtr>
18 public:
20  using guard_ptr = GuardPtr<T, marked_ptr>;
21 
22  concurrent_ptr(const marked_ptr& p = marked_ptr()) noexcept : _ptr(p) {} // NOLINT
23  concurrent_ptr(const concurrent_ptr&) = delete;
24  concurrent_ptr(concurrent_ptr&&) = delete;
25  concurrent_ptr& operator=(const concurrent_ptr&) = delete;
26  concurrent_ptr& operator=(concurrent_ptr&&) = delete;
27 
28  // Atomic load that does not guard target from being reclaimed.
29  [[nodiscard]] marked_ptr load(std::memory_order order = std::memory_order_seq_cst) const { return _ptr.load(order); }
30 
31  // Atomic store.
32  void store(const marked_ptr& src, std::memory_order order = std::memory_order_seq_cst) { _ptr.store(src, order); }
33 
34  // Shorthand for store (src.get())
35  void store(const guard_ptr& src, std::memory_order order = std::memory_order_seq_cst) {
36  _ptr.store(src.get(), order);
37  }
38 
39  bool compare_exchange_weak(marked_ptr& expected,
40  marked_ptr desired,
41  std::memory_order order = std::memory_order_seq_cst) {
42  return _ptr.compare_exchange_weak(expected, desired, order);
43  }
44 
45  bool compare_exchange_weak(marked_ptr& expected,
46  marked_ptr desired,
47  std::memory_order order = std::memory_order_seq_cst) volatile {
48  return _ptr.compare_exchange_weak(expected, desired, order);
49  }
50 
51  bool compare_exchange_weak(marked_ptr& expected,
52  marked_ptr desired,
53  std::memory_order success,
54  std::memory_order failure) {
55  return _ptr.compare_exchange_weak(expected, desired, success, failure);
56  }
57 
58  bool compare_exchange_weak(marked_ptr& expected,
59  marked_ptr desired,
60  std::memory_order success,
61  std::memory_order failure) volatile {
62  return _ptr.compare_exchange_weak(expected, desired, success, failure);
63  }
64 
65  bool compare_exchange_strong(marked_ptr& expected,
66  marked_ptr desired,
67  std::memory_order order = std::memory_order_seq_cst) {
68  return _ptr.compare_exchange_strong(expected, desired, order);
69  }
70 
71  bool compare_exchange_strong(marked_ptr& expected,
72  marked_ptr desired,
73  std::memory_order order = std::memory_order_seq_cst) volatile {
74  return _ptr.compare_exchange_strong(expected, desired, order);
75  }
76 
77  bool compare_exchange_strong(marked_ptr& expected,
78  marked_ptr desired,
79  std::memory_order success,
80  std::memory_order failure) {
81  return _ptr.compare_exchange_strong(expected, desired, success, failure);
82  }
83 
84  bool compare_exchange_strong(marked_ptr& expected,
85  marked_ptr desired,
86  std::memory_order success,
87  std::memory_order failure) volatile {
88  return _ptr.compare_exchange_strong(expected, desired, success, failure);
89  }
90 
91 private:
92  std::atomic<marked_ptr> _ptr;
93 };
94 } // namespace xenium::reclamation::detail
95 
96 #endif
xenium::marked_ptr
A pointer with an embedded mark/tag value.
Definition: marked_ptr.hpp:41
xenium::reclamation::detail::concurrent_ptr
T must be derived from enable_concurrent_ptr<T>. D is a deleter.
Definition: concurrent_ptr.hpp:17