1 /*
2  * Copyright (c) Facebook, Inc. and its affiliates.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <atomic>
20 #include <memory>
21 
22 ///
23 /// Forward declatations and implicit documentation of all hazptr
24 /// top-level classes, functions, macros, default values, and globals.
25 ///
26 
27 /** FOLYY_HAZPTR_THR_LOCAL */
28 #if FOLLY_MOBILE
29 #define FOLLY_HAZPTR_THR_LOCAL false
30 #else
31 #define FOLLY_HAZPTR_THR_LOCAL true
32 #endif
33 
34 namespace folly {
35 
36 ///
37 /// Hazard pointer record.
38 /// Defined in HazptrRec.h
39 ///
40 
41 /** hazptr_rec */
42 template <template <typename> class Atom = std::atomic>
43 class hazptr_rec;
44 
45 ///
46 /// Classes related to objects protectable by hazard pointers.
47 /// Defined in HazptrObj.h
48 ///
49 
50 /** hazptr_obj */
51 template <template <typename> class Atom = std::atomic>
52 class hazptr_obj;
53 
54 /** hazptr_obj_list */
55 template <template <typename> class Atom = std::atomic>
56 class hazptr_obj_list;
57 
58 /** hazptr_obj_cohort */
59 template <template <typename> class Atom = std::atomic>
60 class hazptr_obj_cohort;
61 
62 /** hazptr_obj_retired_list */
63 template <template <typename> class Atom = std::atomic>
64 class hazptr_obj_retired_list;
65 
66 /** hazptr_deleter */
67 template <typename T, typename D>
68 class hazptr_deleter;
69 
70 /** hazptr_obj_base */
71 template <
72     typename T,
73     template <typename> class Atom = std::atomic,
74     typename D = std::default_delete<T>>
75 class hazptr_obj_base;
76 
77 /** hazard_pointer_obj_base
78     class template name consistent with standard proposal */
79 template <
80     typename T,
81     template <typename> class Atom = std::atomic,
82     typename D = std::default_delete<T>>
83 using hazard_pointer_obj_base = hazptr_obj_base<T, Atom, D>;
84 
85 ///
86 /// Classes related to link counted objects and automatic retirement.
87 /// Defined in HazptrLinked.h
88 ///
89 
90 /** hazptr_root */
91 template <typename T, template <typename> class Atom = std::atomic>
92 class hazptr_root;
93 
94 /** hazptr_obj_linked */
95 template <template <typename> class Atom = std::atomic>
96 class hazptr_obj_linked;
97 
98 /** hazptr_obj_base_linked */
99 template <
100     typename T,
101     template <typename> class Atom = std::atomic,
102     typename Deleter = std::default_delete<T>>
103 class hazptr_obj_base_linked;
104 
105 ///
106 /// Classes and functions related to thread local structures.
107 /// Defined in HazptrThrLocal.h
108 ///
109 
110 /** hazptr_tc_entry */
111 template <template <typename> class Atom = std::atomic>
112 class hazptr_tc_entry;
113 
114 /** hazptr_tc */
115 template <template <typename> class Atom = std::atomic>
116 class hazptr_tc;
117 
118 /** hazptr_tc_tls */
119 template <template <typename> class Atom = std::atomic>
120 hazptr_tc<Atom>& hazptr_tc_tls();
121 
122 /** hazptr_tc_evict -- Used only for benchmarking */
123 template <template <typename> class Atom = std::atomic>
124 void hazptr_tc_evict();
125 
126 ///
127 /// Hazard pointer domain
128 /// Defined in HazptrDomain.h
129 ///
130 
131 /** hazptr_domain */
132 template <template <typename> class Atom = std::atomic>
133 class hazptr_domain;
134 
135 /** hazard_pointer_domain
136     class name consistent with standard proposal */
137 template <template <typename> class Atom = std::atomic>
138 using hazard_pointer_domain = hazptr_domain<Atom>;
139 
140 /** default_hazptr_domain */
141 template <template <typename> class Atom = std::atomic>
142 hazptr_domain<Atom>& default_hazptr_domain();
143 
144 /** hazard_pointer_default_domain
145     function name consistent with standard proposal */
146 template <template <typename> class Atom = std::atomic>
147 hazard_pointer_domain<Atom>& hazard_pointer_default_domain();
148 
149 /** hazptr_domain_push_retired */
150 template <template <typename> class Atom = std::atomic>
151 void hazptr_domain_push_retired(
152     hazptr_obj_list<Atom>& l,
153     hazptr_domain<Atom>& domain = default_hazptr_domain<Atom>()) noexcept;
154 
155 /** hazptr_retire */
156 template <
157     template <typename> class Atom = std::atomic,
158     typename T,
159     typename D = std::default_delete<T>>
160 void hazptr_retire(T* obj, D reclaim = {});
161 
162 /** hazptr_cleanup */
163 template <template <typename> class Atom = std::atomic>
164 void hazptr_cleanup(
165     hazptr_domain<Atom>& domain = default_hazptr_domain<Atom>()) noexcept;
166 
167 /** hazard_pointer_clean_up
168     function name consistent with standard proposal */
169 template <template <typename> class Atom = std::atomic>
170 void hazard_pointer_clean_up(
171     hazard_pointer_domain<Atom>& domain =
172         hazard_pointer_default_domain<Atom>()) noexcept;
173 
174 /** Global default domain defined in Hazptr.cpp */
175 extern hazptr_domain<std::atomic> default_domain;
176 
177 /** Defined in Hazptr.cpp */
178 bool hazptr_use_executor();
179 
180 ///
181 /// Classes related to hazard pointer holders.
182 /// Defined in HazptrHolder.h
183 ///
184 
185 /** hazptr_holder */
186 template <template <typename> class Atom = std::atomic>
187 class hazptr_holder;
188 
189 /** hazard_pointer
190     class name consistent with standard proposal  */
191 template <template <typename> class Atom = std::atomic>
192 using hazard_pointer = hazptr_holder<Atom>;
193 
194 /** Free function make_hazard_pointer constructs nonempty holder */
195 template <template <typename> class Atom = std::atomic>
196 hazptr_holder<Atom> make_hazard_pointer(
197     hazptr_domain<Atom>& domain = default_hazptr_domain<Atom>());
198 
199 /** Free function swap of hazptr_holder-s */
200 template <template <typename> class Atom = std::atomic>
201 void swap(hazptr_holder<Atom>&, hazptr_holder<Atom>&) noexcept;
202 
203 /** hazptr_array */
204 template <uint8_t M = 1, template <typename> class Atom = std::atomic>
205 class hazptr_array;
206 
207 /** Free function make_hazard_pointer_array constructs nonempty array */
208 template <uint8_t M = 1, template <typename> class Atom = std::atomic>
209 hazptr_array<M, Atom> make_hazard_pointer_array();
210 
211 /** hazptr_local */
212 template <uint8_t M = 1, template <typename> class Atom = std::atomic>
213 class hazptr_local;
214 
215 } // namespace folly
216