blob: daf64b265909fd4b369ccd8f6609a77fede20665 [file] [log] [blame]
Howard Hinnant8f73c632010-09-27 21:17:38 +00001// -*- C++ -*-
2//===--------------------------- atomic -----------------------------------===//
3//
4// The LLVM Compiler Infrastructure
5//
6// This file is distributed under the University of Illinois Open Source
7// License. See LICENSE.TXT for details.
8//
9//===----------------------------------------------------------------------===//
10
11#ifndef _LIBCPP_ATOMIC
12#define _LIBCPP_ATOMIC
13
14/*
15 atomic synopsis
16
17namespace std
18{
19
20// order and consistency
21
22typedef enum memory_order
23{
Howard Hinnantd1176e22010-09-28 17:13:38 +000024 memory_order_relaxed,
25 memory_order_consume, // load-consume
26 memory_order_acquire, // load-acquire
27 memory_order_release, // store-release
28 memory_order_acq_rel, // store-release load-acquire
29 memory_order_seq_cst // store-release load-acquire
Howard Hinnant8f73c632010-09-27 21:17:38 +000030} memory_order;
31
32template <class T> T kill_dependency(T y);
33
34// lock-free property
35
36#define ATOMIC_CHAR_LOCK_FREE unspecified
37#define ATOMIC_CHAR16_T_LOCK_FREE unspecified
38#define ATOMIC_CHAR32_T_LOCK_FREE unspecified
39#define ATOMIC_WCHAR_T_LOCK_FREE unspecified
40#define ATOMIC_SHORT_LOCK_FREE unspecified
41#define ATOMIC_INT_LOCK_FREE unspecified
42#define ATOMIC_LONG_LOCK_FREE unspecified
43#define ATOMIC_LLONG_LOCK_FREE unspecified
Howard Hinnant8f73c632010-09-27 21:17:38 +000044
Howard Hinnant8f73c632010-09-27 21:17:38 +000045// flag type and operations
46
47typedef struct atomic_flag
48{
Howard Hinnant4777bf22010-12-06 23:10:08 +000049 bool test_and_set(memory_order m = memory_order_seq_cst) volatile;
50 bool test_and_set(memory_order m = memory_order_seq_cst);
51 void clear(memory_order m = memory_order_seq_cst) volatile;
52 void clear(memory_order m = memory_order_seq_cst);
Howard Hinnant8f73c632010-09-27 21:17:38 +000053 atomic_flag() = default;
54 atomic_flag(const atomic_flag&) = delete;
55 atomic_flag& operator=(const atomic_flag&) = delete;
56 atomic_flag& operator=(const atomic_flag&) volatile = delete;
57} atomic_flag;
58
Howard Hinnant4777bf22010-12-06 23:10:08 +000059bool
60 atomic_flag_test_and_set(volatile atomic_flag* obj);
61
62bool
63 atomic_flag_test_and_set(atomic_flag* obj);
64
65bool
66 atomic_flag_test_and_set_explicit(volatile atomic_flag* obj,
67 memory_order m);
68
69bool
70 atomic_flag_test_and_set_explicit(atomic_flag* obj, memory_order m);
71
72void
73 atomic_flag_clear(volatile atomic_flag* obj);
74
75void
76 atomic_flag_clear(atomic_flag* obj);
77
78void
79 atomic_flag_clear_explicit(volatile atomic_flag* obj, memory_order m);
80
81void
82 atomic_flag_clear_explicit(atomic_flag* obj, memory_order m);
Howard Hinnant8f73c632010-09-27 21:17:38 +000083
84#define ATOMIC_FLAG_INIT see below
Howard Hinnante7385012010-10-19 16:51:18 +000085#define ATOMIC_VAR_INIT(value) see below
Howard Hinnant8f73c632010-09-27 21:17:38 +000086
Howard Hinnant8f73c632010-09-27 21:17:38 +000087template <class T>
88struct atomic
89{
90 bool is_lock_free() const volatile;
91 bool is_lock_free() const;
Howard Hinnant4777bf22010-12-06 23:10:08 +000092 void store(T desr, memory_order m = memory_order_seq_cst) volatile;
93 void store(T desr, memory_order m = memory_order_seq_cst);
94 T load(memory_order m = memory_order_seq_cst) const volatile;
95 T load(memory_order m = memory_order_seq_cst) const;
Howard Hinnant8f73c632010-09-27 21:17:38 +000096 operator T() const volatile;
97 operator T() const;
Howard Hinnant4777bf22010-12-06 23:10:08 +000098 T exchange(T desr, memory_order m = memory_order_seq_cst) volatile;
99 T exchange(T desr, memory_order m = memory_order_seq_cst);
100 bool compare_exchange_weak(T& expc, T desr,
101 memory_order s, memory_order f) volatile;
102 bool compare_exchange_weak(T& expc, T desr, memory_order s, memory_order f);
103 bool compare_exchange_strong(T& expc, T desr,
104 memory_order s, memory_order f) volatile;
105 bool compare_exchange_strong(T& expc, T desr,
106 memory_order s, memory_order f);
107 bool compare_exchange_weak(T& expc, T desr,
108 memory_order m = memory_order_seq_cst) volatile;
109 bool compare_exchange_weak(T& expc, T desr,
110 memory_order m = memory_order_seq_cst);
111 bool compare_exchange_strong(T& expc, T desr,
112 memory_order m = memory_order_seq_cst) volatile;
113 bool compare_exchange_strong(T& expc, T desr,
114 memory_order m = memory_order_seq_cst);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000115
116 atomic() = default;
Howard Hinnant4777bf22010-12-06 23:10:08 +0000117 constexpr atomic(T desr);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000118 atomic(const atomic&) = delete;
119 atomic& operator=(const atomic&) = delete;
120 atomic& operator=(const atomic&) volatile = delete;
121 T operator=(T) volatile;
122 T operator=(T);
123};
124
125template <>
Howard Hinnant4777bf22010-12-06 23:10:08 +0000126struct atomic<integral>
Howard Hinnant8f73c632010-09-27 21:17:38 +0000127{
Howard Hinnant4777bf22010-12-06 23:10:08 +0000128 bool is_lock_free() const volatile;
129 bool is_lock_free() const;
130 void store(integral desr, memory_order m = memory_order_seq_cst) volatile;
131 void store(integral desr, memory_order m = memory_order_seq_cst);
132 integral load(memory_order m = memory_order_seq_cst) const volatile;
133 integral load(memory_order m = memory_order_seq_cst) const;
134 operator integral() const volatile;
135 operator integral() const;
136 integral exchange(integral desr,
137 memory_order m = memory_order_seq_cst) volatile;
138 integral exchange(integral desr, memory_order m = memory_order_seq_cst);
139 bool compare_exchange_weak(integral& expc, integral desr,
140 memory_order s, memory_order f) volatile;
141 bool compare_exchange_weak(integral& expc, integral desr,
142 memory_order s, memory_order f);
143 bool compare_exchange_strong(integral& expc, integral desr,
144 memory_order s, memory_order f) volatile;
145 bool compare_exchange_strong(integral& expc, integral desr,
146 memory_order s, memory_order f);
147 bool compare_exchange_weak(integral& expc, integral desr,
148 memory_order m = memory_order_seq_cst) volatile;
149 bool compare_exchange_weak(integral& expc, integral desr,
150 memory_order m = memory_order_seq_cst);
151 bool compare_exchange_strong(integral& expc, integral desr,
152 memory_order m = memory_order_seq_cst) volatile;
153 bool compare_exchange_strong(integral& expc, integral desr,
154 memory_order m = memory_order_seq_cst);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000155
Howard Hinnant4777bf22010-12-06 23:10:08 +0000156 integral
157 fetch_add(integral op, memory_order m = memory_order_seq_cst) volatile;
158 integral fetch_add(integral op, memory_order m = memory_order_seq_cst);
159 integral
160 fetch_sub(integral op, memory_order m = memory_order_seq_cst) volatile;
161 integral fetch_sub(integral op, memory_order m = memory_order_seq_cst);
162 integral
163 fetch_and(integral op, memory_order m = memory_order_seq_cst) volatile;
164 integral fetch_and(integral op, memory_order m = memory_order_seq_cst);
165 integral
166 fetch_or(integral op, memory_order m = memory_order_seq_cst) volatile;
167 integral fetch_or(integral op, memory_order m = memory_order_seq_cst);
168 integral
169 fetch_xor(integral op, memory_order m = memory_order_seq_cst) volatile;
170 integral fetch_xor(integral op, memory_order m = memory_order_seq_cst);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000171
Howard Hinnant8f73c632010-09-27 21:17:38 +0000172 atomic() = default;
Howard Hinnant4777bf22010-12-06 23:10:08 +0000173 constexpr atomic(integral desr);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000174 atomic(const atomic&) = delete;
175 atomic& operator=(const atomic&) = delete;
176 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant4777bf22010-12-06 23:10:08 +0000177 integral operator=(integral desr) volatile;
178 integral operator=(integral desr);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000179
Howard Hinnant4777bf22010-12-06 23:10:08 +0000180 integral operator++(int) volatile;
181 integral operator++(int);
182 integral operator--(int) volatile;
183 integral operator--(int);
184 integral operator++() volatile;
185 integral operator++();
186 integral operator--() volatile;
187 integral operator--();
188 integral operator+=(integral op) volatile;
189 integral operator+=(integral op);
190 integral operator-=(integral op) volatile;
191 integral operator-=(integral op);
192 integral operator&=(integral op) volatile;
193 integral operator&=(integral op);
194 integral operator|=(integral op) volatile;
195 integral operator|=(integral op);
Howard Hinnant91e2f262010-12-07 20:46:14 +0000196 integral operator^=(integral op) volatile;
197 integral operator^=(integral op);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000198};
199
200template <class T>
201struct atomic<T*>
Howard Hinnant8f73c632010-09-27 21:17:38 +0000202{
Howard Hinnant4777bf22010-12-06 23:10:08 +0000203 bool is_lock_free() const volatile;
204 bool is_lock_free() const;
205 void store(T* desr, memory_order m = memory_order_seq_cst) volatile;
206 void store(T* desr, memory_order m = memory_order_seq_cst);
207 T* load(memory_order m = memory_order_seq_cst) const volatile;
208 T* load(memory_order m = memory_order_seq_cst) const;
Howard Hinnant8f73c632010-09-27 21:17:38 +0000209 operator T*() const volatile;
210 operator T*() const;
Howard Hinnant4777bf22010-12-06 23:10:08 +0000211 T* exchange(T* desr, memory_order m = memory_order_seq_cst) volatile;
212 T* exchange(T* desr, memory_order m = memory_order_seq_cst);
213 bool compare_exchange_weak(T*& expc, T* desr,
214 memory_order s, memory_order f) volatile;
215 bool compare_exchange_weak(T*& expc, T* desr,
216 memory_order s, memory_order f);
217 bool compare_exchange_strong(T*& expc, T* desr,
218 memory_order s, memory_order f) volatile;
219 bool compare_exchange_strong(T*& expc, T* desr,
220 memory_order s, memory_order f);
221 bool compare_exchange_weak(T*& expc, T* desr,
222 memory_order m = memory_order_seq_cst) volatile;
223 bool compare_exchange_weak(T*& expc, T* desr,
224 memory_order m = memory_order_seq_cst);
225 bool compare_exchange_strong(T*& expc, T* desr,
226 memory_order m = memory_order_seq_cst) volatile;
227 bool compare_exchange_strong(T*& expc, T* desr,
228 memory_order m = memory_order_seq_cst);
229 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile;
230 T* fetch_add(ptrdiff_t op, memory_order m = memory_order_seq_cst);
231 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst) volatile;
232 T* fetch_sub(ptrdiff_t op, memory_order m = memory_order_seq_cst);
233
Howard Hinnant8f73c632010-09-27 21:17:38 +0000234 atomic() = default;
Howard Hinnant4777bf22010-12-06 23:10:08 +0000235 constexpr atomic(T* desr);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000236 atomic(const atomic&) = delete;
237 atomic& operator=(const atomic&) = delete;
238 atomic& operator=(const atomic&) volatile = delete;
Howard Hinnant4777bf22010-12-06 23:10:08 +0000239
Howard Hinnant8f73c632010-09-27 21:17:38 +0000240 T* operator=(T*) volatile;
241 T* operator=(T*);
242 T* operator++(int) volatile;
243 T* operator++(int);
244 T* operator--(int) volatile;
245 T* operator--(int);
246 T* operator++() volatile;
247 T* operator++();
248 T* operator--() volatile;
249 T* operator--();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000250 T* operator+=(ptrdiff_t op) volatile;
251 T* operator+=(ptrdiff_t op);
252 T* operator-=(ptrdiff_t op) volatile;
253 T* operator-=(ptrdiff_t op);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000254};
255
Howard Hinnant4777bf22010-12-06 23:10:08 +0000256
257template <class T>
258 bool
259 atomic_is_lock_free(const volatile atomic<T>* obj);
260
261template <class T>
262 bool
263 atomic_is_lock_free(const atomic<T>* obj);
264
265template <class T>
266 void
267 atomic_init(volatile atomic<T>* obj, T desr);
268
269template <class T>
270 void
271 atomic_init(atomic<T>* obj, T desr);
272
273template <class T>
274 void
275 atomic_store(volatile atomic<T>* obj, T desr);
276
277template <class T>
278 void
279 atomic_store(atomic<T>* obj, T desr);
280
281template <class T>
282 void
283 atomic_store_explicit(volatile atomic<T>* obj, T desr, memory_order m);
284
285template <class T>
286 void
287 atomic_store_explicit(atomic<T>* obj, T desr, memory_order m);
288
289template <class T>
290 T
291 atomic_load(const volatile atomic<T>* obj);
292
293template <class T>
294 T
295 atomic_load(const atomic<T>* obj);
296
297template <class T>
298 T
299 atomic_load_explicit(const volatile atomic<T>* obj, memory_order m);
300
301template <class T>
302 T
303 atomic_load_explicit(const atomic<T>* obj, memory_order m);
304
305template <class T>
306 T
307 atomic_exchange(volatile atomic<T>* obj, T desr);
308
309template <class T>
310 T
311 atomic_exchange(atomic<T>* obj, T desr);
312
313template <class T>
314 T
315 atomic_exchange_explicit(volatile atomic<T>* obj, T desr, memory_order m);
316
317template <class T>
318 T
319 atomic_exchange_explicit(atomic<T>* obj, T desr, memory_order m);
320
321template <class T>
322 bool
323 atomic_compare_exchange_weak(volatile atomic<T>* obj, T* expc, T desr);
324
325template <class T>
326 bool
327 atomic_compare_exchange_weak(atomic<T>* obj, T* expc, T desr);
328
329template <class T>
330 bool
331 atomic_compare_exchange_strong(volatile atomic<T>* obj, T* expc, T desr);
332
333template <class T>
334 bool
335 atomic_compare_exchange_strong(atomic<T>* obj, T* expc, T desr);
336
337template <class T>
338 bool
339 atomic_compare_exchange_weak_explicit(volatile atomic<T>* obj, T* expc,
340 T desr,
341 memory_order s, memory_order f);
342
343template <class T>
344 bool
345 atomic_compare_exchange_weak_explicit(atomic<T>* obj, T* expc, T desr,
346 memory_order s, memory_order f);
347
348template <class T>
349 bool
350 atomic_compare_exchange_strong_explicit(volatile atomic<T>* obj,
351 T* expc, T desr,
352 memory_order s, memory_order f);
353
354template <class T>
355 bool
356 atomic_compare_exchange_strong_explicit(atomic<T>* obj, T* expc,
357 T desr,
358 memory_order s, memory_order f);
359
360template <class Integral>
361 Integral
362 atomic_fetch_add(volatile atomic<Integral>* obj, Integral op);
363
364template <class Integral>
365 Integral
366 atomic_fetch_add(atomic<Integral>* obj, Integral op);
367
368template <class Integral>
369 Integral
370 atomic_fetch_add_explicit(volatile atomic<Integral>* obj, Integral op,
371 memory_order m);
372template <class Integral>
373 Integral
374 atomic_fetch_add_explicit(atomic<Integral>* obj, Integral op,
375 memory_order m);
376template <class Integral>
377 Integral
378 atomic_fetch_sub(volatile atomic<Integral>* obj, Integral op);
379
380template <class Integral>
381 Integral
382 atomic_fetch_sub(atomic<Integral>* obj, Integral op);
383
384template <class Integral>
385 Integral
386 atomic_fetch_sub_explicit(volatile atomic<Integral>* obj, Integral op,
387 memory_order m);
388template <class Integral>
389 Integral
390 atomic_fetch_sub_explicit(atomic<Integral>* obj, Integral op,
391 memory_order m);
392template <class Integral>
393 Integral
394 atomic_fetch_and(volatile atomic<Integral>* obj, Integral op);
395
396template <class Integral>
397 Integral
398 atomic_fetch_and(atomic<Integral>* obj, Integral op);
399
400template <class Integral>
401 Integral
402 atomic_fetch_and_explicit(volatile atomic<Integral>* obj, Integral op,
403 memory_order m);
404template <class Integral>
405 Integral
406 atomic_fetch_and_explicit(atomic<Integral>* obj, Integral op,
407 memory_order m);
408template <class Integral>
409 Integral
410 atomic_fetch_or(volatile atomic<Integral>* obj, Integral op);
411
412template <class Integral>
413 Integral
414 atomic_fetch_or(atomic<Integral>* obj, Integral op);
415
416template <class Integral>
417 Integral
418 atomic_fetch_or_explicit(volatile atomic<Integral>* obj, Integral op,
419 memory_order m);
420template <class Integral>
421 Integral
422 atomic_fetch_or_explicit(atomic<Integral>* obj, Integral op,
423 memory_order m);
424template <class Integral>
425 Integral
426 atomic_fetch_xor(volatile atomic<Integral>* obj, Integral op);
427
428template <class Integral>
429 Integral
430 atomic_fetch_xor(atomic<Integral>* obj, Integral op);
431
432template <class Integral>
433 Integral
434 atomic_fetch_xor_explicit(volatile atomic<Integral>* obj, Integral op,
435 memory_order m);
436template <class Integral>
437 Integral
438 atomic_fetch_xor_explicit(atomic<Integral>* obj, Integral op,
439 memory_order m);
440
441template <class T>
442 T*
443 atomic_fetch_add(volatile atomic<T*>* obj, ptrdiff_t op);
444
445template <class T>
446 T*
447 atomic_fetch_add(atomic<T*>* obj, ptrdiff_t op);
448
449template <class T>
450 T*
451 atomic_fetch_add_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
452 memory_order m);
453template <class T>
454 T*
455 atomic_fetch_add_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
456
457template <class T>
458 T*
459 atomic_fetch_sub(volatile atomic<T*>* obj, ptrdiff_t op);
460
461template <class T>
462 T*
463 atomic_fetch_sub(atomic<T*>* obj, ptrdiff_t op);
464
465template <class T>
466 T*
467 atomic_fetch_sub_explicit(volatile atomic<T*>* obj, ptrdiff_t op,
468 memory_order m);
469template <class T>
470 T*
471 atomic_fetch_sub_explicit(atomic<T*>* obj, ptrdiff_t op, memory_order m);
472
473// Atomics for standard typedef types
474
475typedef atomic<char> atomic_char;
476typedef atomic<signed char> atomic_schar;
477typedef atomic<unsigned char> atomic_uchar;
478typedef atomic<short> atomic_short;
479typedef atomic<unsigned short> atomic_ushort;
480typedef atomic<int> atomic_int;
481typedef atomic<unsigned int> atomic_uint;
482typedef atomic<long> atomic_long;
483typedef atomic<unsigned long> atomic_ulong;
484typedef atomic<long long> atomic_llong;
485typedef atomic<unsigned long long> atomic_ullong;
486typedef atomic<char16_t> atomic_char16_t;
487typedef atomic<char32_t> atomic_char32_t;
488typedef atomic<wchar_t> atomic_wchar_t;
489
490typedef atomic<int_least8_t> atomic_int_least8_t;
491typedef atomic<uint_least8_t> atomic_uint_least8_t;
492typedef atomic<int_least16_t> atomic_int_least16_t;
493typedef atomic<uint_least16_t> atomic_uint_least16_t;
494typedef atomic<int_least32_t> atomic_int_least32_t;
495typedef atomic<uint_least32_t> atomic_uint_least32_t;
496typedef atomic<int_least64_t> atomic_int_least64_t;
497typedef atomic<uint_least64_t> atomic_uint_least64_t;
498
499typedef atomic<int_fast8_t> atomic_int_fast8_t;
500typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
501typedef atomic<int_fast16_t> atomic_int_fast16_t;
502typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
503typedef atomic<int_fast32_t> atomic_int_fast32_t;
504typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
505typedef atomic<int_fast64_t> atomic_int_fast64_t;
506typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
507
508typedef atomic<intptr_t> atomic_intptr_t;
509typedef atomic<uintptr_t> atomic_uintptr_t;
510typedef atomic<size_t> atomic_size_t;
511typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
512typedef atomic<intmax_t> atomic_intmax_t;
513typedef atomic<uintmax_t> atomic_uintmax_t;
514
Howard Hinnant8f73c632010-09-27 21:17:38 +0000515// fences
516
Howard Hinnant4777bf22010-12-06 23:10:08 +0000517void atomic_thread_fence(memory_order m);
518void atomic_signal_fence(memory_order m);
Howard Hinnant8f73c632010-09-27 21:17:38 +0000519
520} // std
521
522*/
523
524#include <__config>
Howard Hinnant4777bf22010-12-06 23:10:08 +0000525#include <cstddef>
526#include <cstdint>
527#include <type_traits>
Howard Hinnant8f73c632010-09-27 21:17:38 +0000528
529#pragma GCC system_header
530
531_LIBCPP_BEGIN_NAMESPACE_STD
532
Howard Hinnantd1176e22010-09-28 17:13:38 +0000533typedef enum memory_order
534{
535 memory_order_relaxed, memory_order_consume, memory_order_acquire,
536 memory_order_release, memory_order_acq_rel, memory_order_seq_cst
537} memory_order;
538
539template <class _Tp>
540inline _LIBCPP_INLINE_VISIBILITY
541_Tp
542kill_dependency(_Tp __y)
543{
544 return __y;
545}
Howard Hinnant8f73c632010-09-27 21:17:38 +0000546
Howard Hinnant91e2f262010-12-07 20:46:14 +0000547// general atomic<T>
548
549template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
550struct __atomic_base // false
551{
552 _Tp __a_;
553
554 _LIBCPP_INLINE_VISIBILITY
555 bool is_lock_free() const volatile
556 {return __atomic_is_lock_free(_Tp());}
557 _LIBCPP_INLINE_VISIBILITY
558 bool is_lock_free() const
559 {return __atomic_is_lock_free(_Tp());}
560 _LIBCPP_INLINE_VISIBILITY
561 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile
562 {__atomic_store(&__a_, __d, __m);}
563 _LIBCPP_INLINE_VISIBILITY
564 void store(_Tp __d, memory_order __m = memory_order_seq_cst)
565 {__atomic_store(&__a_, __d, __m);}
566 _LIBCPP_INLINE_VISIBILITY
567 _Tp load(memory_order __m = memory_order_seq_cst) const volatile
568 {return __atomic_load(&__a_, __m);}
569 _LIBCPP_INLINE_VISIBILITY
570 _Tp load(memory_order __m = memory_order_seq_cst) const
571 {return __atomic_load(&__a_, __m);}
572 _LIBCPP_INLINE_VISIBILITY
573 operator _Tp() const volatile {return load();}
574 _LIBCPP_INLINE_VISIBILITY
575 operator _Tp() const {return load();}
576 _LIBCPP_INLINE_VISIBILITY
577 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile
578 {return __atomic_exchange(&__a_, __d, __m);}
579 _LIBCPP_INLINE_VISIBILITY
580 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst)
581 {return __atomic_exchange(&__a_, __d, __m);}
582 _LIBCPP_INLINE_VISIBILITY
583 bool compare_exchange_weak(_Tp& __e, _Tp __d,
584 memory_order __s, memory_order __f) volatile
585 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
586 _LIBCPP_INLINE_VISIBILITY
587 bool compare_exchange_weak(_Tp& __e, _Tp __d,
588 memory_order __s, memory_order __f)
589 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
590 _LIBCPP_INLINE_VISIBILITY
591 bool compare_exchange_strong(_Tp& __e, _Tp __d,
592 memory_order __s, memory_order __f) volatile
593 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
594 _LIBCPP_INLINE_VISIBILITY
595 bool compare_exchange_strong(_Tp& __e, _Tp __d,
596 memory_order __s, memory_order __f)
597 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
598 _LIBCPP_INLINE_VISIBILITY
599 bool compare_exchange_weak(_Tp& __e, _Tp __d,
600 memory_order __m = memory_order_seq_cst) volatile
601 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
602 _LIBCPP_INLINE_VISIBILITY
603 bool compare_exchange_weak(_Tp& __e, _Tp __d,
604 memory_order __m = memory_order_seq_cst)
605 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
606 _LIBCPP_INLINE_VISIBILITY
607 bool compare_exchange_strong(_Tp& __e, _Tp __d,
608 memory_order __m = memory_order_seq_cst) volatile
609 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
610 _LIBCPP_INLINE_VISIBILITY
611 bool compare_exchange_strong(_Tp& __e, _Tp __d,
612 memory_order __m = memory_order_seq_cst)
613 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
614
615 _LIBCPP_INLINE_VISIBILITY
616 __atomic_base() {} // = default;
617 _LIBCPP_INLINE_VISIBILITY
618 /*constexpr*/ __atomic_base(_Tp __d) : __a_(__d) {}
Howard Hinnant770d1c42010-12-08 17:20:28 +0000619#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
Howard Hinnant91e2f262010-12-07 20:46:14 +0000620 __atomic_base(const __atomic_base&) = delete;
621 __atomic_base& operator=(const __atomic_base&) = delete;
622 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Howard Hinnant770d1c42010-12-08 17:20:28 +0000623#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
624private:
625 __atomic_base(const __atomic_base&);
626 __atomic_base& operator=(const __atomic_base&);
627 __atomic_base& operator=(const __atomic_base&) volatile;
628#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
Howard Hinnant91e2f262010-12-07 20:46:14 +0000629};
630
631// atomic<Integral>
632
633template <class _Tp>
634struct __atomic_base<_Tp, true>
635 : public __atomic_base<_Tp, false>
636{
637 typedef __atomic_base<_Tp, false> __base;
638 _LIBCPP_INLINE_VISIBILITY
639 __atomic_base() {} // = default;
640 _LIBCPP_INLINE_VISIBILITY
641 /*constexpr*/ __atomic_base(_Tp __d) : __base(__d) {}
642
643 _LIBCPP_INLINE_VISIBILITY
644 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
645 {return __atomic_fetch_add(&this->__a_, __op, __m);}
646 _LIBCPP_INLINE_VISIBILITY
647 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst)
648 {return __atomic_fetch_add(&this->__a_, __op, __m);}
649 _LIBCPP_INLINE_VISIBILITY
650 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
651 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
652 _LIBCPP_INLINE_VISIBILITY
653 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst)
654 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
655 _LIBCPP_INLINE_VISIBILITY
656 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
657 {return __atomic_fetch_and(&this->__a_, __op, __m);}
658 _LIBCPP_INLINE_VISIBILITY
659 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst)
660 {return __atomic_fetch_and(&this->__a_, __op, __m);}
661 _LIBCPP_INLINE_VISIBILITY
662 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
663 {return __atomic_fetch_or(&this->__a_, __op, __m);}
664 _LIBCPP_INLINE_VISIBILITY
665 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst)
666 {return __atomic_fetch_or(&this->__a_, __op, __m);}
667 _LIBCPP_INLINE_VISIBILITY
668 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
669 {return __atomic_fetch_xor(&this->__a_, __op, __m);}
670 _LIBCPP_INLINE_VISIBILITY
671 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst)
672 {return __atomic_fetch_xor(&this->__a_, __op, __m);}
673
674 _LIBCPP_INLINE_VISIBILITY
675 _Tp operator++(int) volatile {return fetch_add(_Tp(1));}
676 _LIBCPP_INLINE_VISIBILITY
677 _Tp operator++(int) {return fetch_add(_Tp(1));}
678 _LIBCPP_INLINE_VISIBILITY
679 _Tp operator--(int) volatile {return fetch_sub(_Tp(1));}
680 _LIBCPP_INLINE_VISIBILITY
681 _Tp operator--(int) {return fetch_sub(_Tp(1));}
682 _LIBCPP_INLINE_VISIBILITY
683 _Tp operator++() volatile {return fetch_add(_Tp(1)) + _Tp(1);}
684 _LIBCPP_INLINE_VISIBILITY
685 _Tp operator++() {return fetch_add(_Tp(1)) + _Tp(1);}
686 _LIBCPP_INLINE_VISIBILITY
687 _Tp operator--() volatile {return fetch_sub(_Tp(1)) - _Tp(1);}
688 _LIBCPP_INLINE_VISIBILITY
689 _Tp operator--() {return fetch_sub(_Tp(1)) - _Tp(1);}
690 _LIBCPP_INLINE_VISIBILITY
691 _Tp operator+=(_Tp __op) volatile {return fetch_add(__op) + __op;}
692 _LIBCPP_INLINE_VISIBILITY
693 _Tp operator+=(_Tp __op) {return fetch_add(__op) + __op;}
694 _LIBCPP_INLINE_VISIBILITY
695 _Tp operator-=(_Tp __op) volatile {return fetch_sub(__op) - __op;}
696 _LIBCPP_INLINE_VISIBILITY
697 _Tp operator-=(_Tp __op) {return fetch_sub(__op) - __op;}
698 _LIBCPP_INLINE_VISIBILITY
699 _Tp operator&=(_Tp __op) volatile {return fetch_and(__op) & __op;}
700 _LIBCPP_INLINE_VISIBILITY
701 _Tp operator&=(_Tp __op) {return fetch_and(__op) & __op;}
702 _LIBCPP_INLINE_VISIBILITY
703 _Tp operator|=(_Tp __op) volatile {return fetch_or(__op) | __op;}
704 _LIBCPP_INLINE_VISIBILITY
705 _Tp operator|=(_Tp __op) {return fetch_or(__op) | __op;}
706 _LIBCPP_INLINE_VISIBILITY
707 _Tp operator^=(_Tp __op) volatile {return fetch_xor(__op) ^ __op;}
708 _LIBCPP_INLINE_VISIBILITY
709 _Tp operator^=(_Tp __op) {return fetch_xor(__op) ^ __op;}
710};
711
712// atomic<T>
713
714template <class _Tp>
715struct atomic
716 : public __atomic_base<_Tp>
717{
718 typedef __atomic_base<_Tp> __base;
719 _LIBCPP_INLINE_VISIBILITY
720 atomic() {} // = default;
721 _LIBCPP_INLINE_VISIBILITY
722 /*constexpr*/ atomic(_Tp __d) : __base(__d) {}
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000723
724 _LIBCPP_INLINE_VISIBILITY
725 _Tp operator=(_Tp __d) volatile
726 {__base::store(__d); return __d;}
727 _LIBCPP_INLINE_VISIBILITY
728 _Tp operator=(_Tp __d)
729 {__base::store(__d); return __d;}
Howard Hinnant91e2f262010-12-07 20:46:14 +0000730};
731
732// atomic<T*>
733
734template <class _Tp>
735struct atomic<_Tp*>
736 : public __atomic_base<_Tp*>
737{
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000738 typedef __atomic_base<_Tp*> __base;
Howard Hinnant91e2f262010-12-07 20:46:14 +0000739 _LIBCPP_INLINE_VISIBILITY
740 atomic() {} // = default;
741 _LIBCPP_INLINE_VISIBILITY
742 /*constexpr*/ atomic(_Tp* __d) : __base(__d) {}
743
744 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000745 _Tp* operator=(_Tp* __d) volatile
746 {__base::store(__d); return __d;}
747 _LIBCPP_INLINE_VISIBILITY
748 _Tp* operator=(_Tp* __d)
749 {__base::store(__d); return __d;}
750
751 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91e2f262010-12-07 20:46:14 +0000752 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
753 volatile
754 {return __atomic_fetch_add(&this->__a_, __op, __m);}
755 _LIBCPP_INLINE_VISIBILITY
756 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
757 {return __atomic_fetch_add(&this->__a_, __op, __m);}
758 _LIBCPP_INLINE_VISIBILITY
759 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
760 volatile
761 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
762 _LIBCPP_INLINE_VISIBILITY
763 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
764 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
765
766 _LIBCPP_INLINE_VISIBILITY
767 _Tp* operator++(int) volatile {return fetch_add(1);}
768 _LIBCPP_INLINE_VISIBILITY
769 _Tp* operator++(int) {return fetch_add(1);}
770 _LIBCPP_INLINE_VISIBILITY
771 _Tp* operator--(int) volatile {return fetch_sub(1);}
772 _LIBCPP_INLINE_VISIBILITY
773 _Tp* operator--(int) {return fetch_sub(1);}
774 _LIBCPP_INLINE_VISIBILITY
775 _Tp* operator++() volatile {return fetch_add(1) + 1;}
776 _LIBCPP_INLINE_VISIBILITY
777 _Tp* operator++() {return fetch_add(1) + 1;}
778 _LIBCPP_INLINE_VISIBILITY
779 _Tp* operator--() volatile {return fetch_sub(1) - 1;}
780 _LIBCPP_INLINE_VISIBILITY
781 _Tp* operator--() {return fetch_sub(1) - 1;}
782 _LIBCPP_INLINE_VISIBILITY
783 _Tp* operator+=(ptrdiff_t __op) volatile {return fetch_add(__op) + __op;}
784 _LIBCPP_INLINE_VISIBILITY
785 _Tp* operator+=(ptrdiff_t __op) {return fetch_add(__op) + __op;}
786 _LIBCPP_INLINE_VISIBILITY
787 _Tp* operator-=(ptrdiff_t __op) volatile {return fetch_sub(__op) - __op;}
788 _LIBCPP_INLINE_VISIBILITY
789 _Tp* operator-=(ptrdiff_t __op) {return fetch_sub(__op) - __op;}
790};
Howard Hinnant4777bf22010-12-06 23:10:08 +0000791
792// atomic_is_lock_free
793
794template <class _Tp>
795inline _LIBCPP_INLINE_VISIBILITY
796bool
Howard Hinnant91e2f262010-12-07 20:46:14 +0000797atomic_is_lock_free(const volatile atomic<_Tp>* __o)
Howard Hinnant4777bf22010-12-06 23:10:08 +0000798{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000799 return __o->is_lock_free();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000800}
801
802template <class _Tp>
803inline _LIBCPP_INLINE_VISIBILITY
804bool
Howard Hinnant91e2f262010-12-07 20:46:14 +0000805atomic_is_lock_free(const atomic<_Tp>* __o)
Howard Hinnant4777bf22010-12-06 23:10:08 +0000806{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000807 return __o->is_lock_free();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000808}
809
810// atomic_init
811
812template <class _Tp>
813inline _LIBCPP_INLINE_VISIBILITY
814void
815atomic_init(volatile atomic<_Tp>* __o, _Tp __d)
816{
817 __o->__a_ = __d;
818}
819
820template <class _Tp>
821inline _LIBCPP_INLINE_VISIBILITY
822void
823atomic_init(atomic<_Tp>* __o, _Tp __d)
824{
825 __o->__a_ = __d;
826}
827
828// atomic_store
829
830template <class _Tp>
831inline _LIBCPP_INLINE_VISIBILITY
832void
833atomic_store(volatile atomic<_Tp>* __o, _Tp __d)
834{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000835 __o->store(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000836}
837
838template <class _Tp>
839inline _LIBCPP_INLINE_VISIBILITY
840void
841atomic_store(atomic<_Tp>* __o, _Tp __d)
842{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000843 __o->store(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000844}
845
846// atomic_store_explicit
847
848template <class _Tp>
849inline _LIBCPP_INLINE_VISIBILITY
850void
851atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m)
852{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000853 __o->store(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000854}
855
856template <class _Tp>
857inline _LIBCPP_INLINE_VISIBILITY
858void
859atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m)
860{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000861 __o->store(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000862}
863
864// atomic_load
865
866template <class _Tp>
867inline _LIBCPP_INLINE_VISIBILITY
868_Tp
869atomic_load(const volatile atomic<_Tp>* __o)
870{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000871 return __o->load();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000872}
873
874template <class _Tp>
875inline _LIBCPP_INLINE_VISIBILITY
876_Tp
877atomic_load(const atomic<_Tp>* __o)
878{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000879 return __o->load();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000880}
881
882// atomic_load_explicit
883
884template <class _Tp>
885inline _LIBCPP_INLINE_VISIBILITY
886_Tp
887atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m)
888{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000889 return __o->load(__m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000890}
891
892template <class _Tp>
893inline _LIBCPP_INLINE_VISIBILITY
894_Tp
895atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m)
896{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000897 return __o->load(__m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000898}
899
900// atomic_exchange
901
902template <class _Tp>
903inline _LIBCPP_INLINE_VISIBILITY
904_Tp
905atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d)
906{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000907 return __o->exchange(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000908}
909
910template <class _Tp>
911inline _LIBCPP_INLINE_VISIBILITY
912_Tp
913atomic_exchange(atomic<_Tp>* __o, _Tp __d)
914{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000915 return __o->exchange(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000916}
917
918// atomic_exchange_explicit
919
920template <class _Tp>
921inline _LIBCPP_INLINE_VISIBILITY
922_Tp
923atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m)
924{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000925 return __o->exchange(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000926}
927
928template <class _Tp>
929inline _LIBCPP_INLINE_VISIBILITY
930_Tp
931atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m)
932{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000933 return __o->exchange(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000934}
935
936// atomic_compare_exchange_weak
937
938template <class _Tp>
939inline _LIBCPP_INLINE_VISIBILITY
940bool
941atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d)
942{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000943 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000944}
945
946template <class _Tp>
947inline _LIBCPP_INLINE_VISIBILITY
948bool
949atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d)
950{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000951 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000952}
953
954// atomic_compare_exchange_strong
955
956template <class _Tp>
957inline _LIBCPP_INLINE_VISIBILITY
958bool
959atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d)
960{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000961 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000962}
963
964template <class _Tp>
965inline _LIBCPP_INLINE_VISIBILITY
966bool
967atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d)
968{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000969 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000970}
971
972// atomic_compare_exchange_weak_explicit
973
974template <class _Tp>
975inline _LIBCPP_INLINE_VISIBILITY
976bool
977atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
978 _Tp __d,
979 memory_order __s, memory_order __f)
980{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000981 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000982}
983
984template <class _Tp>
985inline _LIBCPP_INLINE_VISIBILITY
986bool
987atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
988 memory_order __s, memory_order __f)
989{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000990 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000991}
992
993// atomic_compare_exchange_strong_explicit
994
995template <class _Tp>
996inline _LIBCPP_INLINE_VISIBILITY
997bool
998atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
999 _Tp* __e, _Tp __d,
1000 memory_order __s, memory_order __f)
1001{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001002 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001003}
1004
1005template <class _Tp>
1006inline _LIBCPP_INLINE_VISIBILITY
1007bool
1008atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1009 _Tp __d,
1010 memory_order __s, memory_order __f)
1011{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001012 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001013}
1014
Howard Hinnant91e2f262010-12-07 20:46:14 +00001015// atomic_fetch_add
Howard Hinnant4777bf22010-12-06 23:10:08 +00001016
1017template <class _Tp>
Howard Hinnant91e2f262010-12-07 20:46:14 +00001018inline _LIBCPP_INLINE_VISIBILITY
1019typename enable_if
1020<
1021 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1022 _Tp
1023>::type
1024atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op)
Howard Hinnant4777bf22010-12-06 23:10:08 +00001025{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001026 return __o->fetch_add(__op);
1027}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001028
Howard Hinnant91e2f262010-12-07 20:46:14 +00001029template <class _Tp>
1030inline _LIBCPP_INLINE_VISIBILITY
1031typename enable_if
1032<
1033 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1034 _Tp
1035>::type
1036atomic_fetch_add(atomic<_Tp>* __o, _Tp __op)
1037{
1038 return __o->fetch_add(__op);
1039}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001040
Howard Hinnant91e2f262010-12-07 20:46:14 +00001041template <class _Tp>
1042inline _LIBCPP_INLINE_VISIBILITY
1043_Tp*
1044atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op)
1045{
1046 return __o->fetch_add(__op);
1047}
1048
1049template <class _Tp>
1050inline _LIBCPP_INLINE_VISIBILITY
1051_Tp*
1052atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op)
1053{
1054 return __o->fetch_add(__op);
1055}
1056
1057// atomic_fetch_add_explicit
1058
1059template <class _Tp>
1060inline _LIBCPP_INLINE_VISIBILITY
1061typename enable_if
1062<
1063 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1064 _Tp
1065>::type
1066atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1067{
1068 return __o->fetch_add(__op, __m);
1069}
1070
1071template <class _Tp>
1072inline _LIBCPP_INLINE_VISIBILITY
1073typename enable_if
1074<
1075 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1076 _Tp
1077>::type
1078atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1079{
1080 return __o->fetch_add(__op, __m);
1081}
1082
1083template <class _Tp>
1084inline _LIBCPP_INLINE_VISIBILITY
1085_Tp*
1086atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1087 memory_order __m)
1088{
1089 return __o->fetch_add(__op, __m);
1090}
1091
1092template <class _Tp>
1093inline _LIBCPP_INLINE_VISIBILITY
1094_Tp*
1095atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m)
1096{
1097 return __o->fetch_add(__op, __m);
1098}
1099
1100// atomic_fetch_sub
1101
1102template <class _Tp>
1103inline _LIBCPP_INLINE_VISIBILITY
1104typename enable_if
1105<
1106 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1107 _Tp
1108>::type
1109atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op)
1110{
1111 return __o->fetch_sub(__op);
1112}
1113
1114template <class _Tp>
1115inline _LIBCPP_INLINE_VISIBILITY
1116typename enable_if
1117<
1118 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1119 _Tp
1120>::type
1121atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op)
1122{
1123 return __o->fetch_sub(__op);
1124}
1125
1126template <class _Tp>
1127inline _LIBCPP_INLINE_VISIBILITY
1128_Tp*
1129atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op)
1130{
1131 return __o->fetch_sub(__op);
1132}
1133
1134template <class _Tp>
1135inline _LIBCPP_INLINE_VISIBILITY
1136_Tp*
1137atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op)
1138{
1139 return __o->fetch_sub(__op);
1140}
1141
1142// atomic_fetch_sub_explicit
1143
1144template <class _Tp>
1145inline _LIBCPP_INLINE_VISIBILITY
1146typename enable_if
1147<
1148 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1149 _Tp
1150>::type
1151atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1152{
1153 return __o->fetch_sub(__op, __m);
1154}
1155
1156template <class _Tp>
1157inline _LIBCPP_INLINE_VISIBILITY
1158typename enable_if
1159<
1160 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1161 _Tp
1162>::type
1163atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1164{
1165 return __o->fetch_sub(__op, __m);
1166}
1167
1168template <class _Tp>
1169inline _LIBCPP_INLINE_VISIBILITY
1170_Tp*
1171atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1172 memory_order __m)
1173{
1174 return __o->fetch_sub(__op, __m);
1175}
1176
1177template <class _Tp>
1178inline _LIBCPP_INLINE_VISIBILITY
1179_Tp*
1180atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m)
1181{
1182 return __o->fetch_sub(__op, __m);
1183}
1184
1185// atomic_fetch_and
1186
1187template <class _Tp>
1188inline _LIBCPP_INLINE_VISIBILITY
1189typename enable_if
1190<
1191 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1192 _Tp
1193>::type
1194atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op)
1195{
1196 return __o->fetch_and(__op);
1197}
1198
1199template <class _Tp>
1200inline _LIBCPP_INLINE_VISIBILITY
1201typename enable_if
1202<
1203 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1204 _Tp
1205>::type
1206atomic_fetch_and(atomic<_Tp>* __o, _Tp __op)
1207{
1208 return __o->fetch_and(__op);
1209}
1210
1211// atomic_fetch_and_explicit
1212
1213template <class _Tp>
1214inline _LIBCPP_INLINE_VISIBILITY
1215typename enable_if
1216<
1217 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1218 _Tp
1219>::type
1220atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1221{
1222 return __o->fetch_and(__op, __m);
1223}
1224
1225template <class _Tp>
1226inline _LIBCPP_INLINE_VISIBILITY
1227typename enable_if
1228<
1229 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1230 _Tp
1231>::type
1232atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1233{
1234 return __o->fetch_and(__op, __m);
1235}
1236
1237// atomic_fetch_or
1238
1239template <class _Tp>
1240inline _LIBCPP_INLINE_VISIBILITY
1241typename enable_if
1242<
1243 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1244 _Tp
1245>::type
1246atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op)
1247{
1248 return __o->fetch_or(__op);
1249}
1250
1251template <class _Tp>
1252inline _LIBCPP_INLINE_VISIBILITY
1253typename enable_if
1254<
1255 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1256 _Tp
1257>::type
1258atomic_fetch_or(atomic<_Tp>* __o, _Tp __op)
1259{
1260 return __o->fetch_or(__op);
1261}
1262
1263// atomic_fetch_or_explicit
1264
1265template <class _Tp>
1266inline _LIBCPP_INLINE_VISIBILITY
1267typename enable_if
1268<
1269 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1270 _Tp
1271>::type
1272atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1273{
1274 return __o->fetch_or(__op, __m);
1275}
1276
1277template <class _Tp>
1278inline _LIBCPP_INLINE_VISIBILITY
1279typename enable_if
1280<
1281 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1282 _Tp
1283>::type
1284atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1285{
1286 return __o->fetch_or(__op, __m);
1287}
1288
1289// atomic_fetch_xor
1290
1291template <class _Tp>
1292inline _LIBCPP_INLINE_VISIBILITY
1293typename enable_if
1294<
1295 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1296 _Tp
1297>::type
1298atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op)
1299{
1300 return __o->fetch_xor(__op);
1301}
1302
1303template <class _Tp>
1304inline _LIBCPP_INLINE_VISIBILITY
1305typename enable_if
1306<
1307 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1308 _Tp
1309>::type
1310atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op)
1311{
1312 return __o->fetch_xor(__op);
1313}
1314
1315// atomic_fetch_xor_explicit
1316
1317template <class _Tp>
1318inline _LIBCPP_INLINE_VISIBILITY
1319typename enable_if
1320<
1321 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1322 _Tp
1323>::type
1324atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1325{
1326 return __o->fetch_xor(__op, __m);
1327}
1328
1329template <class _Tp>
1330inline _LIBCPP_INLINE_VISIBILITY
1331typename enable_if
1332<
1333 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1334 _Tp
1335>::type
1336atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1337{
1338 return __o->fetch_xor(__op, __m);
1339}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001340
Howard Hinnant770d1c42010-12-08 17:20:28 +00001341// flag type and operations
1342
1343typedef struct atomic_flag
1344{
1345 bool __a_;
1346
1347 _LIBCPP_INLINE_VISIBILITY
1348 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile
1349 {return __atomic_exchange(&__a_, true, __m);}
1350 _LIBCPP_INLINE_VISIBILITY
1351 bool test_and_set(memory_order __m = memory_order_seq_cst)
1352 {return __atomic_exchange(&__a_, true, __m);}
1353 _LIBCPP_INLINE_VISIBILITY
1354 void clear(memory_order __m = memory_order_seq_cst) volatile
1355 {__atomic_store(&__a_, false, __m);}
1356 _LIBCPP_INLINE_VISIBILITY
1357 void clear(memory_order __m = memory_order_seq_cst)
1358 {__atomic_store(&__a_, false, __m);}
1359
1360 _LIBCPP_INLINE_VISIBILITY
1361 atomic_flag() {} // = default;
1362 _LIBCPP_INLINE_VISIBILITY
1363 atomic_flag(bool __b) : __a_(__b) {}
1364
1365#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1366 atomic_flag(const atomic_flag&) = delete;
1367 atomic_flag& operator=(const atomic_flag&) = delete;
1368 atomic_flag& operator=(const atomic_flag&) volatile = delete;
1369#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1370private:
1371 atomic_flag(const atomic_flag&);
1372 atomic_flag& operator=(const atomic_flag&);
1373 atomic_flag& operator=(const atomic_flag&) volatile;
1374#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1375} atomic_flag;
1376
1377inline _LIBCPP_INLINE_VISIBILITY
1378bool
1379atomic_flag_test_and_set(volatile atomic_flag* __o)
1380{
1381 return __o->test_and_set();
1382}
1383
1384inline _LIBCPP_INLINE_VISIBILITY
1385bool
1386atomic_flag_test_and_set(atomic_flag* __o)
1387{
1388 return __o->test_and_set();
1389}
1390
1391inline _LIBCPP_INLINE_VISIBILITY
1392bool
1393atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m)
1394{
1395 return __o->test_and_set(__m);
1396}
1397
1398inline _LIBCPP_INLINE_VISIBILITY
1399bool
1400atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m)
1401{
1402 return __o->test_and_set(__m);
1403}
1404
1405inline _LIBCPP_INLINE_VISIBILITY
1406void
1407atomic_flag_clear(volatile atomic_flag* __o)
1408{
1409 __o->clear();
1410}
1411
1412inline _LIBCPP_INLINE_VISIBILITY
1413void
1414atomic_flag_clear(atomic_flag* __o)
1415{
1416 __o->clear();
1417}
1418
1419inline _LIBCPP_INLINE_VISIBILITY
1420void
1421atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m)
1422{
1423 __o->clear(__m);
1424}
1425
1426inline _LIBCPP_INLINE_VISIBILITY
1427void
1428atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m)
1429{
1430 __o->clear(__m);
1431}
1432
1433// fences
1434
1435inline _LIBCPP_INLINE_VISIBILITY
1436void
1437atomic_thread_fence(memory_order __m)
1438{
1439 __atomic_thread_fence(__m);
1440}
1441
1442inline _LIBCPP_INLINE_VISIBILITY
1443void
1444atomic_signal_fence(memory_order __m)
1445{
1446 __atomic_signal_fence(__m);
1447}
1448
Howard Hinnantd2f6afb2010-12-07 23:24:41 +00001449// Atomics for standard typedef types
1450
1451typedef atomic<char> atomic_char;
1452typedef atomic<signed char> atomic_schar;
1453typedef atomic<unsigned char> atomic_uchar;
1454typedef atomic<short> atomic_short;
1455typedef atomic<unsigned short> atomic_ushort;
1456typedef atomic<int> atomic_int;
1457typedef atomic<unsigned int> atomic_uint;
1458typedef atomic<long> atomic_long;
1459typedef atomic<unsigned long> atomic_ulong;
1460typedef atomic<long long> atomic_llong;
1461typedef atomic<unsigned long long> atomic_ullong;
1462typedef atomic<char16_t> atomic_char16_t;
1463typedef atomic<char32_t> atomic_char32_t;
1464typedef atomic<wchar_t> atomic_wchar_t;
1465
1466typedef atomic<int_least8_t> atomic_int_least8_t;
1467typedef atomic<uint_least8_t> atomic_uint_least8_t;
1468typedef atomic<int_least16_t> atomic_int_least16_t;
1469typedef atomic<uint_least16_t> atomic_uint_least16_t;
1470typedef atomic<int_least32_t> atomic_int_least32_t;
1471typedef atomic<uint_least32_t> atomic_uint_least32_t;
1472typedef atomic<int_least64_t> atomic_int_least64_t;
1473typedef atomic<uint_least64_t> atomic_uint_least64_t;
1474
1475typedef atomic<int_fast8_t> atomic_int_fast8_t;
1476typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1477typedef atomic<int_fast16_t> atomic_int_fast16_t;
1478typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1479typedef atomic<int_fast32_t> atomic_int_fast32_t;
1480typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1481typedef atomic<int_fast64_t> atomic_int_fast64_t;
1482typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1483
1484typedef atomic<intptr_t> atomic_intptr_t;
1485typedef atomic<uintptr_t> atomic_uintptr_t;
1486typedef atomic<size_t> atomic_size_t;
1487typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1488typedef atomic<intmax_t> atomic_intmax_t;
1489typedef atomic<uintmax_t> atomic_uintmax_t;
1490
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001491#define ATOMIC_FLAG_INIT {false}
Howard Hinnant611fdaf2010-10-04 18:52:54 +00001492#define ATOMIC_VAR_INIT(__v) {__v}
1493
Howard Hinnant770d1c42010-12-08 17:20:28 +00001494// lock-free property
Howard Hinnant611fdaf2010-10-04 18:52:54 +00001495
Howard Hinnant770d1c42010-12-08 17:20:28 +00001496#define ATOMIC_CHAR_LOCK_FREE 0
1497#define ATOMIC_CHAR16_T_LOCK_FREE 0
1498#define ATOMIC_CHAR32_T_LOCK_FREE 0
1499#define ATOMIC_WCHAR_T_LOCK_FREE 0
1500#define ATOMIC_SHORT_LOCK_FREE 0
1501#define ATOMIC_INT_LOCK_FREE 0
1502#define ATOMIC_LONG_LOCK_FREE 0
1503#define ATOMIC_LLONG_LOCK_FREE 0
1504
Howard Hinnant8f73c632010-09-27 21:17:38 +00001505_LIBCPP_END_NAMESPACE_STD
1506
1507#endif // _LIBCPP_ATOMIC