42 #ifndef G4atomic_defines_hh_
43 #define G4atomic_defines_hh_
47 #ifdef G4MULTITHREADED
62 template <
typename _Tp>
63 using OpFunction = std::function<_Tp(const _Tp&, const _Tp&)>;
65 template <
typename _Tp>
66 inline void do_fetch_and_store(std::atomic<_Tp>* _atomic,
68 std::memory_order mem_odr)
70 _atomic->store(_value, mem_odr);
73 template <
typename _Tp>
74 inline void do_fetch_and_store(std::atomic<_Tp>* _atomic,
75 const std::atomic<_Tp>& _value,
76 std::memory_order mem_odr)
78 _atomic->store(_value.load(), mem_odr);
81 template <
typename _Tp>
82 inline void do_compare_and_swap(std::atomic<_Tp>* _atomic,
84 const OpFunction<_Tp>& _operator,
85 std::memory_order mem_odr)
87 _Tp _expected = _Tp();
89 _expected = _atomic->load();
90 }
while (!(_atomic->compare_exchange_weak(_expected,
96 template <
typename _Tp>
97 inline void do_compare_and_swap(std::atomic<_Tp>* _atomic,
98 const std::atomic<_Tp>&
100 const OpFunction<_Tp>& _operator,
101 std::memory_order mem_odr)
103 _Tp _expected = _Tp();
105 _expected = _atomic->load();
106 }
while (!(_atomic->compare_exchange_weak(_expected,
108 _atomic_value.load()),
116 template <
typename T>
117 inline void set(std::atomic<T>* _atomic,
119 std::memory_order mem_odr
120 = std::memory_order_seq_cst)
122 details::do_compare_and_swap(_atomic,
124 details::OpFunction<T>
125 ([](
const T&,
const T& y){
return y;}),
129 template <
typename T>
130 inline void set(std::atomic<T>& _atomic,
132 std::memory_order mem_odr
133 = std::memory_order_seq_cst)
135 set(&_atomic, _desired, mem_odr);
138 template <
typename T>
139 inline void increment(std::atomic<T>* _atomic,
141 std::memory_order mem_odr)
143 details::do_compare_and_swap(_atomic, _increment,
144 details::OpFunction<T>
145 ([](
const T& x,
const T& y){
return x+y;}),
149 template <
typename T>
150 inline void decrement(std::atomic<T>* _atomic,
const T& _decrement,
151 std::memory_order mem_odr)
153 details::do_compare_and_swap(_atomic, _decrement,
154 details::OpFunction<T>
155 ([](
const T& x,
const T& y){
return x-y;}),
159 template <
typename T>
160 inline void multiply(std::atomic<T>* _atomic,
const T& _factor,
161 std::memory_order mem_odr)
163 details::do_compare_and_swap(_atomic, _factor,
164 details::OpFunction<T>
165 ([](
const T& x,
const T& y){
return x*y;}),
169 template <
typename T>
170 inline void divide(std::atomic<T>* _atomic,
const T& _factor,
171 std::memory_order mem_odr)
173 details::do_compare_and_swap(_atomic, _factor,
174 details::OpFunction<T>
175 ([](
const T& x,
const T& y){
return x/y;}),
181 template <
typename T>
182 inline void set(std::atomic<T>* _atomic,
183 const std::atomic<T>& _atomic_desired,
184 std::memory_order mem_odr
185 = std::memory_order_seq_cst)
188 details::do_compare_and_swap(_atomic, _atomic_desired,
189 details::OpFunction<T>
190 ([](
const T&,
const T& y){
return y;}),
194 template <
typename T>
195 inline void set(std::atomic<T>& _atomic,
196 const std::atomic<T>& _atomic_desired,
197 std::memory_order mem_odr)
199 set(&_atomic, _atomic_desired, mem_odr);
202 template <
typename T>
203 inline void increment(std::atomic<T>* _atomic,
204 const std::atomic<T>& _atomic_increment,
205 std::memory_order mem_odr)
207 details::do_compare_and_swap(_atomic, _atomic_increment,
208 details::OpFunction<T>
209 ([](
const T& x,
const T& y){
return x+y;}),
213 template <
typename T>
214 inline void decrement(std::atomic<T>* _atomic,
215 const std::atomic<T>& _atomic_decrement,
216 std::memory_order mem_odr)
218 details::do_compare_and_swap(_atomic, _atomic_decrement,
219 details::OpFunction<T>
220 ([](
const T& x,
const T& y){
return x-y;}),
224 template <
typename T>
225 inline void multiply(std::atomic<T>* _atomic,
226 const std::atomic<T>& _atomic_factor,
227 std::memory_order mem_odr)
229 details::do_compare_and_swap(_atomic, _atomic_factor,
230 details::OpFunction<T>
231 ([](
const T& x,
const T& y){
return x*y;}),
235 template <
typename T>
236 inline void divide(std::atomic<T>* _atomic,
237 const std::atomic<T>& _atomic_factor,
238 std::memory_order mem_odr)
240 details::do_compare_and_swap(_atomic, _atomic_factor,
241 details::OpFunction<T>
242 ([](
const T& x,
const T& y){
return x/y;}),
249 template <
typename T>
250 inline void set(T* _non_atomic,
const T& _desired)
252 *_non_atomic = _desired;
255 template <
typename T>
256 inline void set(T& _non_atomic,
const T& _desired)
258 set(&_non_atomic, _desired);
267 template <
typename T,
typename U>
268 inline void set(std::pair<std::atomic<T>,
269 std::atomic<U> >* _atomic,
270 const std::pair<T, U>& _desired)
272 set(&_atomic->first, _desired.first);
273 set(&_atomic->second, _desired.second);
276 template <
typename T,
typename U>
277 inline void set(std::pair<std::atomic<T>,
278 std::atomic<U> >& _atomic,
279 const std::pair<T, U>& _desired)
281 set(&_atomic, _desired);
284 template <
typename T,
typename U>
285 inline void increment(std::pair<std::atomic<T>,
286 std::atomic<U> >* _atomic,
287 const std::pair<T, U>& _increment)
289 increment(&_atomic->first, _increment.first);
290 increment(&_atomic->second, _increment.second);
293 template <
typename T,
typename U>
294 inline void decrement(std::pair<std::atomic<T>,
295 std::atomic<U> >* _atomic,
296 const std::pair<T, U>& _decrement)
298 decrement(&_atomic->first, _decrement.first);
299 decrement(&_atomic->second, _decrement.second);
302 template <
typename T,
typename U>
303 inline void multiply(std::pair<std::atomic<T>,
304 std::atomic<U> >* _atomic,
305 const std::pair<T, U>& _factor)
307 multiply(&_atomic->first, _factor.first);
308 multiply(&_atomic->second, _factor.second);
311 template <
typename T,
typename U>
312 inline void divide(std::pair<std::atomic<T>,
313 std::atomic<U> >* _atomic,
314 const std::pair<T, U>& _factor)
316 divide(&_atomic->first, _factor.first);
317 divide(&_atomic->second, _factor.second);
322 template <
typename T,
typename U>
323 inline void set(std::pair<std::atomic<T>,
324 std::atomic<U> >* _atomic,
325 const std::pair<std::atomic<T>,
326 std::atomic<U> >& _desired)
328 set(&_atomic->first, _desired.first);
329 set(&_atomic->second, _desired.second);
332 template <
typename T,
typename U>
333 inline void set(std::pair<std::atomic<T>,
334 std::atomic<U> >& _atomic,
335 const std::pair<std::atomic<T>,
336 std::atomic<U> >& _desired)
338 set(&_atomic, _desired);
341 template <
typename T,
typename U>
342 inline void increment(std::pair<std::atomic<T>,
343 std::atomic<U> >* _atomic,
344 const std::pair<std::atomic<T>,
345 std::atomic<U> >& _increment)
347 increment(&_atomic->first, _increment.first);
348 increment(&_atomic->second, _increment.second);
351 template <
typename T,
typename U>
352 inline void decrement(std::pair<std::atomic<T>,
353 std::atomic<U> >* _atomic,
354 const std::pair<std::atomic<T>,
355 std::atomic<U> >& _decrement)
357 decrement(&_atomic->first, _decrement.first);
358 decrement(&_atomic->second, _decrement.second);
361 template <
typename T,
typename U>
362 inline void multiply(std::pair<std::atomic<T>,
363 std::atomic<U> >* _atomic,
364 const std::pair<std::atomic<T>,
365 std::atomic<U> >& _factor)
367 multiply(&_atomic->first, _factor.first);
368 multiply(&_atomic->second, _factor.second);
371 template <
typename T,
typename U>
372 inline void divide(std::pair<std::atomic<T>,
373 std::atomic<U> >* _atomic,
374 const std::pair<std::atomic<T>,
375 std::atomic<U> >& _factor)
377 divide(&_atomic->first, _factor.first);
378 divide(&_atomic->second, _factor.second);
384 template <
typename T>
385 inline T
get(
const T& _non_atomic)
390 template <
typename T>
391 inline T
get(
const T& _non_atomic, std::memory_order)
396 template <
typename T>
397 inline T
get(
const std::atomic<T>& _atomic)
399 return _atomic.load();
402 template <
typename T>
403 inline T
get(
const std::atomic<T>& _atomic,
404 std::memory_order mem_odr)
406 return _atomic.load(mem_odr);
409 template <
typename T,
typename U>
410 inline std::pair<T, U>
get(
const std::pair<std::atomic<T>,
411 std::atomic<U> >& _atomic)
413 return std::pair<T, U>(
get(_atomic.first),
get(_atomic.second));
416 template <
typename T,
typename U>
417 inline std::pair<T, U>
get(
const std::pair<std::atomic<T>,
418 std::atomic<U> >& _atomic,
419 std::memory_order mem_odr)
421 return std::pair<T, U>(
get(_atomic.first, mem_odr),
422 get(_atomic.second, mem_odr));
430 template <
typename _Tp_base,
typename _Tp_atom>
431 inline _Tp_base base(
const _Tp_atom& _atomic)
441 #endif // G4MULTITHREADED
443 #endif // atomic_typedefs_hh_