41 #ifndef G4atomic_defines_hh_
42 #define G4atomic_defines_hh_
46 #ifdef G4MULTITHREADED
61 template <
typename _Tp>
62 using OpFunction = std::function<_Tp(const _Tp&, const _Tp&)>;
64 template <
typename _Tp>
65 inline void do_fetch_and_store(std::atomic<_Tp>* _atomic,
67 std::memory_order mem_odr)
69 _atomic->store(_value, mem_odr);
72 template <
typename _Tp>
73 inline void do_fetch_and_store(std::atomic<_Tp>* _atomic,
74 const std::atomic<_Tp>& _value,
75 std::memory_order mem_odr)
77 _atomic->store(_value.load(), mem_odr);
80 template <
typename _Tp>
81 inline void do_compare_and_swap(std::atomic<_Tp>* _atomic,
83 const OpFunction<_Tp>& _operator,
84 std::memory_order mem_odr)
86 _Tp _expected = _Tp();
88 _expected = _atomic->load();
89 }
while (!(_atomic->compare_exchange_weak(_expected,
95 template <
typename _Tp>
96 inline void do_compare_and_swap(std::atomic<_Tp>* _atomic,
97 const std::atomic<_Tp>&
99 const OpFunction<_Tp>& _operator,
100 std::memory_order mem_odr)
102 _Tp _expected = _Tp();
104 _expected = _atomic->load();
105 }
while (!(_atomic->compare_exchange_weak(_expected,
107 _atomic_value.load()),
115 template <
typename T>
116 inline void set(std::atomic<T>* _atomic,
118 std::memory_order mem_odr
119 = std::memory_order_seq_cst)
121 details::do_compare_and_swap(_atomic,
123 details::OpFunction<T>
124 ([](
const T&,
const T&
y){
return y;}),
128 template <
typename T>
129 inline void set(std::atomic<T>& _atomic,
131 std::memory_order mem_odr
132 = std::memory_order_seq_cst)
134 set(&_atomic, _desired, mem_odr);
137 template <
typename T>
138 inline void increment(std::atomic<T>* _atomic,
140 std::memory_order mem_odr)
142 details::do_compare_and_swap(_atomic, _increment,
143 details::OpFunction<T>
144 ([](
const T&
x,
const T&
y){
return x+
y;}),
148 template <
typename T>
149 inline void decrement(std::atomic<T>* _atomic,
const T& _decrement,
150 std::memory_order mem_odr)
152 details::do_compare_and_swap(_atomic, _decrement,
153 details::OpFunction<T>
154 ([](
const T&
x,
const T&
y){
return x-
y;}),
158 template <
typename T>
159 inline void multiply(std::atomic<T>* _atomic,
const T& _factor,
160 std::memory_order mem_odr)
162 details::do_compare_and_swap(_atomic, _factor,
163 details::OpFunction<T>
164 ([](
const T&
x,
const T&
y){
return x*
y;}),
168 template <
typename T>
169 inline void divide(std::atomic<T>* _atomic,
const T& _factor,
170 std::memory_order mem_odr)
172 details::do_compare_and_swap(_atomic, _factor,
173 details::OpFunction<T>
174 ([](
const T&
x,
const T&
y){
return x/
y;}),
180 template <
typename T>
181 inline void set(std::atomic<T>* _atomic,
182 const std::atomic<T>& _atomic_desired,
183 std::memory_order mem_odr
184 = std::memory_order_seq_cst)
187 details::do_compare_and_swap(_atomic, _atomic_desired,
188 details::OpFunction<T>
189 ([](
const T&,
const T&
y){
return y;}),
193 template <
typename T>
194 inline void set(std::atomic<T>& _atomic,
195 const std::atomic<T>& _atomic_desired,
196 std::memory_order mem_odr)
198 set(&_atomic, _atomic_desired, mem_odr);
201 template <
typename T>
202 inline void increment(std::atomic<T>* _atomic,
203 const std::atomic<T>& _atomic_increment,
204 std::memory_order mem_odr)
206 details::do_compare_and_swap(_atomic, _atomic_increment,
207 details::OpFunction<T>
208 ([](
const T&
x,
const T&
y){
return x+
y;}),
212 template <
typename T>
213 inline void decrement(std::atomic<T>* _atomic,
214 const std::atomic<T>& _atomic_decrement,
215 std::memory_order mem_odr)
217 details::do_compare_and_swap(_atomic, _atomic_decrement,
218 details::OpFunction<T>
219 ([](
const T&
x,
const T&
y){
return x-
y;}),
223 template <
typename T>
224 inline void multiply(std::atomic<T>* _atomic,
225 const std::atomic<T>& _atomic_factor,
226 std::memory_order mem_odr)
228 details::do_compare_and_swap(_atomic, _atomic_factor,
229 details::OpFunction<T>
230 ([](
const T&
x,
const T&
y){
return x*
y;}),
234 template <
typename T>
235 inline void divide(std::atomic<T>* _atomic,
236 const std::atomic<T>& _atomic_factor,
237 std::memory_order mem_odr)
239 details::do_compare_and_swap(_atomic, _atomic_factor,
240 details::OpFunction<T>
241 ([](
const T&
x,
const T&
y){
return x/
y;}),
248 template <
typename T>
249 inline void set(
T* _non_atomic,
const T& _desired)
251 *_non_atomic = _desired;
254 template <
typename T>
255 inline void set(
T& _non_atomic,
const T& _desired)
257 set(&_non_atomic, _desired);
266 template <
typename T,
typename U>
267 inline void set(std::pair<std::atomic<T>,
268 std::atomic<U> >* _atomic,
269 const std::pair<T, U>& _desired)
271 set(&_atomic->first, _desired.first);
272 set(&_atomic->second, _desired.second);
275 template <
typename T,
typename U>
276 inline void set(std::pair<std::atomic<T>,
277 std::atomic<U> >& _atomic,
278 const std::pair<T, U>& _desired)
280 set(&_atomic, _desired);
283 template <
typename T,
typename U>
284 inline void increment(std::pair<std::atomic<T>,
285 std::atomic<U> >* _atomic,
286 const std::pair<T, U>& _increment)
288 increment(&_atomic->first, _increment.first);
289 increment(&_atomic->second, _increment.second);
292 template <
typename T,
typename U>
293 inline void decrement(std::pair<std::atomic<T>,
294 std::atomic<U> >* _atomic,
295 const std::pair<T, U>& _decrement)
297 decrement(&_atomic->first, _decrement.first);
298 decrement(&_atomic->second, _decrement.second);
301 template <
typename T,
typename U>
302 inline void multiply(std::pair<std::atomic<T>,
303 std::atomic<U> >* _atomic,
304 const std::pair<T, U>& _factor)
306 multiply(&_atomic->first, _factor.first);
307 multiply(&_atomic->second, _factor.second);
310 template <
typename T,
typename U>
311 inline void divide(std::pair<std::atomic<T>,
312 std::atomic<U> >* _atomic,
313 const std::pair<T, U>& _factor)
315 divide(&_atomic->first, _factor.first);
316 divide(&_atomic->second, _factor.second);
321 template <
typename T,
typename U>
322 inline void set(std::pair<std::atomic<T>,
323 std::atomic<U> >* _atomic,
324 const std::pair<std::atomic<T>,
325 std::atomic<U> >& _desired)
327 set(&_atomic->first, _desired.first);
328 set(&_atomic->second, _desired.second);
331 template <
typename T,
typename U>
332 inline void set(std::pair<std::atomic<T>,
333 std::atomic<U> >& _atomic,
334 const std::pair<std::atomic<T>,
335 std::atomic<U> >& _desired)
337 set(&_atomic, _desired);
340 template <
typename T,
typename U>
341 inline void increment(std::pair<std::atomic<T>,
342 std::atomic<U> >* _atomic,
343 const std::pair<std::atomic<T>,
344 std::atomic<U> >& _increment)
346 increment(&_atomic->first, _increment.first);
347 increment(&_atomic->second, _increment.second);
350 template <
typename T,
typename U>
351 inline void decrement(std::pair<std::atomic<T>,
352 std::atomic<U> >* _atomic,
353 const std::pair<std::atomic<T>,
354 std::atomic<U> >& _decrement)
356 decrement(&_atomic->first, _decrement.first);
357 decrement(&_atomic->second, _decrement.second);
360 template <
typename T,
typename U>
361 inline void multiply(std::pair<std::atomic<T>,
362 std::atomic<U> >* _atomic,
363 const std::pair<std::atomic<T>,
364 std::atomic<U> >& _factor)
366 multiply(&_atomic->first, _factor.first);
367 multiply(&_atomic->second, _factor.second);
370 template <
typename T,
typename U>
371 inline void divide(std::pair<std::atomic<T>,
372 std::atomic<U> >* _atomic,
373 const std::pair<std::atomic<T>,
374 std::atomic<U> >& _factor)
376 divide(&_atomic->first, _factor.first);
377 divide(&_atomic->second, _factor.second);
383 template <
typename T>
384 inline T get(
const T& _non_atomic)
389 template <
typename T>
390 inline T get(
const T& _non_atomic, std::memory_order)
395 template <
typename T>
396 inline T get(
const std::atomic<T>& _atomic)
398 return _atomic.load();
401 template <
typename T>
402 inline T get(
const std::atomic<T>& _atomic,
403 std::memory_order mem_odr)
405 return _atomic.load(mem_odr);
408 template <
typename T,
typename U>
409 inline std::pair<T, U>
get(
const std::pair<std::atomic<T>,
410 std::atomic<U> >& _atomic)
412 return std::pair<T, U>(
get(_atomic.first),
get(_atomic.second));
415 template <
typename T,
typename U>
416 inline std::pair<T, U>
get(
const std::pair<std::atomic<T>,
417 std::atomic<U> >& _atomic,
418 std::memory_order mem_odr)
420 return std::pair<T, U>(
get(_atomic.first, mem_odr),
421 get(_atomic.second, mem_odr));
429 template <
typename _Tp_base,
typename _Tp_atom>
430 inline _Tp_base
base(
const _Tp_atom& _atomic)
440 #endif // G4MULTITHREADED
442 #endif // atomic_typedefs_hh_