xenium
Loading...
Searching...
No Matches
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/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/allocation_tracker.hpp>
14
15#include <xenium/acquire_guard.hpp>
16
17namespace xenium { namespace reclamation {
18
23 {
24 template <class T, class MarkedPtr>
25 class guard_ptr;
26
27 public:
28 template <class T, std::size_t N = 0, class Deleter = std::default_delete<T>>
29 class enable_concurrent_ptr;
30
31 struct region_guard
32 {
33 region_guard() noexcept;
34 ~region_guard() noexcept;
35
36 region_guard(const region_guard&) = delete;
37 region_guard(region_guard&&) = delete;
38 region_guard& operator=(const region_guard&) = delete;
39 region_guard& operator=(region_guard&&) = delete;
40 };
41
42 template <class T, std::size_t N = T::number_of_mark_bits>
44
45 ALLOCATION_TRACKER;
46 private:
47 static constexpr unsigned number_epochs = 3;
48
49 struct thread_data;
50 struct thread_control_block;
51
52 inline static std::atomic<unsigned> global_epoch;
53 inline static detail::thread_block_list<thread_control_block> global_thread_block_list;
54 static thread_data& local_thread_data();
55
56 ALLOCATION_TRACKING_FUNCTIONS;
57 };
58
59 template <class T, std::size_t N, class Deleter>
60 class quiescent_state_based::enable_concurrent_ptr :
61 private detail::deletable_object_impl<T, Deleter>,
62 private detail::tracked_object<quiescent_state_based>
63 {
64 public:
65 static constexpr std::size_t number_of_mark_bits = N;
66 protected:
67 enable_concurrent_ptr() noexcept = default;
68 enable_concurrent_ptr(const enable_concurrent_ptr&) noexcept = default;
69 enable_concurrent_ptr(enable_concurrent_ptr&&) noexcept = default;
70 enable_concurrent_ptr& operator=(const enable_concurrent_ptr&) noexcept = default;
71 enable_concurrent_ptr& operator=(enable_concurrent_ptr&&) noexcept = default;
72 ~enable_concurrent_ptr() noexcept = default;
73 private:
74 friend detail::deletable_object_impl<T, Deleter>;
75
77 friend class guard_ptr;
78 };
79
81 class quiescent_state_based::guard_ptr : public detail::guard_ptr<T, MarkedPtr, guard_ptr<T, MarkedPtr>>
82 {
83 using base = detail::guard_ptr<T, MarkedPtr, guard_ptr>;
84 using Deleter = typename T::Deleter;
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,
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}}
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
T must be derived from enable_concurrent_ptr<T>. D is a deleter.
Definition concurrent_ptr.hpp:21
Quiescent state based reclamation.
Definition quiescent_state_based.hpp:23
Slim wrapper around std::hash with specialization for pointer types.
Definition hash.hpp:25