blob: 31385a23d17a5c041a47a9a0399d6082cd5a4211 [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 Hinnant154002b2011-03-31 16:39:39 +0000533#if !__has_feature(cxx_atomic)
534#error <atomic> is not implemented
535#else
536
Howard Hinnantd1176e22010-09-28 17:13:38 +0000537typedef enum memory_order
538{
539 memory_order_relaxed, memory_order_consume, memory_order_acquire,
540 memory_order_release, memory_order_acq_rel, memory_order_seq_cst
541} memory_order;
542
543template <class _Tp>
544inline _LIBCPP_INLINE_VISIBILITY
545_Tp
546kill_dependency(_Tp __y)
547{
548 return __y;
549}
Howard Hinnant8f73c632010-09-27 21:17:38 +0000550
Howard Hinnant91e2f262010-12-07 20:46:14 +0000551// general atomic<T>
552
553template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
554struct __atomic_base // false
555{
556 _Tp __a_;
557
558 _LIBCPP_INLINE_VISIBILITY
559 bool is_lock_free() const volatile
560 {return __atomic_is_lock_free(_Tp());}
561 _LIBCPP_INLINE_VISIBILITY
562 bool is_lock_free() const
563 {return __atomic_is_lock_free(_Tp());}
564 _LIBCPP_INLINE_VISIBILITY
565 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile
566 {__atomic_store(&__a_, __d, __m);}
567 _LIBCPP_INLINE_VISIBILITY
568 void store(_Tp __d, memory_order __m = memory_order_seq_cst)
569 {__atomic_store(&__a_, __d, __m);}
570 _LIBCPP_INLINE_VISIBILITY
571 _Tp load(memory_order __m = memory_order_seq_cst) const volatile
572 {return __atomic_load(&__a_, __m);}
573 _LIBCPP_INLINE_VISIBILITY
574 _Tp load(memory_order __m = memory_order_seq_cst) const
575 {return __atomic_load(&__a_, __m);}
576 _LIBCPP_INLINE_VISIBILITY
577 operator _Tp() const volatile {return load();}
578 _LIBCPP_INLINE_VISIBILITY
579 operator _Tp() const {return load();}
580 _LIBCPP_INLINE_VISIBILITY
581 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile
582 {return __atomic_exchange(&__a_, __d, __m);}
583 _LIBCPP_INLINE_VISIBILITY
584 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst)
585 {return __atomic_exchange(&__a_, __d, __m);}
586 _LIBCPP_INLINE_VISIBILITY
587 bool compare_exchange_weak(_Tp& __e, _Tp __d,
588 memory_order __s, memory_order __f) volatile
589 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
590 _LIBCPP_INLINE_VISIBILITY
591 bool compare_exchange_weak(_Tp& __e, _Tp __d,
592 memory_order __s, memory_order __f)
593 {return __atomic_compare_exchange_weak(&__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) volatile
597 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
598 _LIBCPP_INLINE_VISIBILITY
599 bool compare_exchange_strong(_Tp& __e, _Tp __d,
600 memory_order __s, memory_order __f)
601 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
602 _LIBCPP_INLINE_VISIBILITY
603 bool compare_exchange_weak(_Tp& __e, _Tp __d,
604 memory_order __m = memory_order_seq_cst) volatile
605 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
606 _LIBCPP_INLINE_VISIBILITY
607 bool compare_exchange_weak(_Tp& __e, _Tp __d,
608 memory_order __m = memory_order_seq_cst)
609 {return __atomic_compare_exchange_weak(&__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) volatile
613 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
614 _LIBCPP_INLINE_VISIBILITY
615 bool compare_exchange_strong(_Tp& __e, _Tp __d,
616 memory_order __m = memory_order_seq_cst)
617 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
618
619 _LIBCPP_INLINE_VISIBILITY
620 __atomic_base() {} // = default;
621 _LIBCPP_INLINE_VISIBILITY
622 /*constexpr*/ __atomic_base(_Tp __d) : __a_(__d) {}
Howard Hinnant770d1c42010-12-08 17:20:28 +0000623#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
Howard Hinnant91e2f262010-12-07 20:46:14 +0000624 __atomic_base(const __atomic_base&) = delete;
625 __atomic_base& operator=(const __atomic_base&) = delete;
626 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Howard Hinnant770d1c42010-12-08 17:20:28 +0000627#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
628private:
629 __atomic_base(const __atomic_base&);
630 __atomic_base& operator=(const __atomic_base&);
631 __atomic_base& operator=(const __atomic_base&) volatile;
632#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
Howard Hinnant91e2f262010-12-07 20:46:14 +0000633};
634
635// atomic<Integral>
636
637template <class _Tp>
638struct __atomic_base<_Tp, true>
639 : public __atomic_base<_Tp, false>
640{
641 typedef __atomic_base<_Tp, false> __base;
642 _LIBCPP_INLINE_VISIBILITY
643 __atomic_base() {} // = default;
644 _LIBCPP_INLINE_VISIBILITY
645 /*constexpr*/ __atomic_base(_Tp __d) : __base(__d) {}
646
647 _LIBCPP_INLINE_VISIBILITY
648 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
649 {return __atomic_fetch_add(&this->__a_, __op, __m);}
650 _LIBCPP_INLINE_VISIBILITY
651 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst)
652 {return __atomic_fetch_add(&this->__a_, __op, __m);}
653 _LIBCPP_INLINE_VISIBILITY
654 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
655 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
656 _LIBCPP_INLINE_VISIBILITY
657 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst)
658 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
659 _LIBCPP_INLINE_VISIBILITY
660 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
661 {return __atomic_fetch_and(&this->__a_, __op, __m);}
662 _LIBCPP_INLINE_VISIBILITY
663 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst)
664 {return __atomic_fetch_and(&this->__a_, __op, __m);}
665 _LIBCPP_INLINE_VISIBILITY
666 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
667 {return __atomic_fetch_or(&this->__a_, __op, __m);}
668 _LIBCPP_INLINE_VISIBILITY
669 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst)
670 {return __atomic_fetch_or(&this->__a_, __op, __m);}
671 _LIBCPP_INLINE_VISIBILITY
672 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
673 {return __atomic_fetch_xor(&this->__a_, __op, __m);}
674 _LIBCPP_INLINE_VISIBILITY
675 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst)
676 {return __atomic_fetch_xor(&this->__a_, __op, __m);}
677
678 _LIBCPP_INLINE_VISIBILITY
679 _Tp operator++(int) volatile {return fetch_add(_Tp(1));}
680 _LIBCPP_INLINE_VISIBILITY
681 _Tp operator++(int) {return fetch_add(_Tp(1));}
682 _LIBCPP_INLINE_VISIBILITY
683 _Tp operator--(int) volatile {return fetch_sub(_Tp(1));}
684 _LIBCPP_INLINE_VISIBILITY
685 _Tp operator--(int) {return fetch_sub(_Tp(1));}
686 _LIBCPP_INLINE_VISIBILITY
687 _Tp operator++() volatile {return fetch_add(_Tp(1)) + _Tp(1);}
688 _LIBCPP_INLINE_VISIBILITY
689 _Tp operator++() {return fetch_add(_Tp(1)) + _Tp(1);}
690 _LIBCPP_INLINE_VISIBILITY
691 _Tp operator--() volatile {return fetch_sub(_Tp(1)) - _Tp(1);}
692 _LIBCPP_INLINE_VISIBILITY
693 _Tp operator--() {return fetch_sub(_Tp(1)) - _Tp(1);}
694 _LIBCPP_INLINE_VISIBILITY
695 _Tp operator+=(_Tp __op) volatile {return fetch_add(__op) + __op;}
696 _LIBCPP_INLINE_VISIBILITY
697 _Tp operator+=(_Tp __op) {return fetch_add(__op) + __op;}
698 _LIBCPP_INLINE_VISIBILITY
699 _Tp operator-=(_Tp __op) volatile {return fetch_sub(__op) - __op;}
700 _LIBCPP_INLINE_VISIBILITY
701 _Tp operator-=(_Tp __op) {return fetch_sub(__op) - __op;}
702 _LIBCPP_INLINE_VISIBILITY
703 _Tp operator&=(_Tp __op) volatile {return fetch_and(__op) & __op;}
704 _LIBCPP_INLINE_VISIBILITY
705 _Tp operator&=(_Tp __op) {return fetch_and(__op) & __op;}
706 _LIBCPP_INLINE_VISIBILITY
707 _Tp operator|=(_Tp __op) volatile {return fetch_or(__op) | __op;}
708 _LIBCPP_INLINE_VISIBILITY
709 _Tp operator|=(_Tp __op) {return fetch_or(__op) | __op;}
710 _LIBCPP_INLINE_VISIBILITY
711 _Tp operator^=(_Tp __op) volatile {return fetch_xor(__op) ^ __op;}
712 _LIBCPP_INLINE_VISIBILITY
713 _Tp operator^=(_Tp __op) {return fetch_xor(__op) ^ __op;}
714};
715
716// atomic<T>
717
718template <class _Tp>
719struct atomic
720 : public __atomic_base<_Tp>
721{
722 typedef __atomic_base<_Tp> __base;
723 _LIBCPP_INLINE_VISIBILITY
724 atomic() {} // = default;
725 _LIBCPP_INLINE_VISIBILITY
726 /*constexpr*/ atomic(_Tp __d) : __base(__d) {}
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000727
728 _LIBCPP_INLINE_VISIBILITY
729 _Tp operator=(_Tp __d) volatile
730 {__base::store(__d); return __d;}
731 _LIBCPP_INLINE_VISIBILITY
732 _Tp operator=(_Tp __d)
733 {__base::store(__d); return __d;}
Howard Hinnant91e2f262010-12-07 20:46:14 +0000734};
735
736// atomic<T*>
737
738template <class _Tp>
739struct atomic<_Tp*>
740 : public __atomic_base<_Tp*>
741{
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000742 typedef __atomic_base<_Tp*> __base;
Howard Hinnant91e2f262010-12-07 20:46:14 +0000743 _LIBCPP_INLINE_VISIBILITY
744 atomic() {} // = default;
745 _LIBCPP_INLINE_VISIBILITY
746 /*constexpr*/ atomic(_Tp* __d) : __base(__d) {}
747
748 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000749 _Tp* operator=(_Tp* __d) volatile
750 {__base::store(__d); return __d;}
751 _LIBCPP_INLINE_VISIBILITY
752 _Tp* operator=(_Tp* __d)
753 {__base::store(__d); return __d;}
754
755 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91e2f262010-12-07 20:46:14 +0000756 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
757 volatile
758 {return __atomic_fetch_add(&this->__a_, __op, __m);}
759 _LIBCPP_INLINE_VISIBILITY
760 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
761 {return __atomic_fetch_add(&this->__a_, __op, __m);}
762 _LIBCPP_INLINE_VISIBILITY
763 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
764 volatile
765 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
766 _LIBCPP_INLINE_VISIBILITY
767 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
768 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
769
770 _LIBCPP_INLINE_VISIBILITY
771 _Tp* operator++(int) volatile {return fetch_add(1);}
772 _LIBCPP_INLINE_VISIBILITY
773 _Tp* operator++(int) {return fetch_add(1);}
774 _LIBCPP_INLINE_VISIBILITY
775 _Tp* operator--(int) volatile {return fetch_sub(1);}
776 _LIBCPP_INLINE_VISIBILITY
777 _Tp* operator--(int) {return fetch_sub(1);}
778 _LIBCPP_INLINE_VISIBILITY
779 _Tp* operator++() volatile {return fetch_add(1) + 1;}
780 _LIBCPP_INLINE_VISIBILITY
781 _Tp* operator++() {return fetch_add(1) + 1;}
782 _LIBCPP_INLINE_VISIBILITY
783 _Tp* operator--() volatile {return fetch_sub(1) - 1;}
784 _LIBCPP_INLINE_VISIBILITY
785 _Tp* operator--() {return fetch_sub(1) - 1;}
786 _LIBCPP_INLINE_VISIBILITY
787 _Tp* operator+=(ptrdiff_t __op) volatile {return fetch_add(__op) + __op;}
788 _LIBCPP_INLINE_VISIBILITY
789 _Tp* operator+=(ptrdiff_t __op) {return fetch_add(__op) + __op;}
790 _LIBCPP_INLINE_VISIBILITY
791 _Tp* operator-=(ptrdiff_t __op) volatile {return fetch_sub(__op) - __op;}
792 _LIBCPP_INLINE_VISIBILITY
793 _Tp* operator-=(ptrdiff_t __op) {return fetch_sub(__op) - __op;}
794};
Howard Hinnant4777bf22010-12-06 23:10:08 +0000795
796// atomic_is_lock_free
797
798template <class _Tp>
799inline _LIBCPP_INLINE_VISIBILITY
800bool
Howard Hinnant91e2f262010-12-07 20:46:14 +0000801atomic_is_lock_free(const volatile atomic<_Tp>* __o)
Howard Hinnant4777bf22010-12-06 23:10:08 +0000802{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000803 return __o->is_lock_free();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000804}
805
806template <class _Tp>
807inline _LIBCPP_INLINE_VISIBILITY
808bool
Howard Hinnant91e2f262010-12-07 20:46:14 +0000809atomic_is_lock_free(const atomic<_Tp>* __o)
Howard Hinnant4777bf22010-12-06 23:10:08 +0000810{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000811 return __o->is_lock_free();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000812}
813
814// atomic_init
815
816template <class _Tp>
817inline _LIBCPP_INLINE_VISIBILITY
818void
819atomic_init(volatile atomic<_Tp>* __o, _Tp __d)
820{
821 __o->__a_ = __d;
822}
823
824template <class _Tp>
825inline _LIBCPP_INLINE_VISIBILITY
826void
827atomic_init(atomic<_Tp>* __o, _Tp __d)
828{
829 __o->__a_ = __d;
830}
831
832// atomic_store
833
834template <class _Tp>
835inline _LIBCPP_INLINE_VISIBILITY
836void
837atomic_store(volatile atomic<_Tp>* __o, _Tp __d)
838{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000839 __o->store(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000840}
841
842template <class _Tp>
843inline _LIBCPP_INLINE_VISIBILITY
844void
845atomic_store(atomic<_Tp>* __o, _Tp __d)
846{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000847 __o->store(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000848}
849
850// atomic_store_explicit
851
852template <class _Tp>
853inline _LIBCPP_INLINE_VISIBILITY
854void
855atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m)
856{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000857 __o->store(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000858}
859
860template <class _Tp>
861inline _LIBCPP_INLINE_VISIBILITY
862void
863atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m)
864{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000865 __o->store(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000866}
867
868// atomic_load
869
870template <class _Tp>
871inline _LIBCPP_INLINE_VISIBILITY
872_Tp
873atomic_load(const volatile atomic<_Tp>* __o)
874{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000875 return __o->load();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000876}
877
878template <class _Tp>
879inline _LIBCPP_INLINE_VISIBILITY
880_Tp
881atomic_load(const atomic<_Tp>* __o)
882{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000883 return __o->load();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000884}
885
886// atomic_load_explicit
887
888template <class _Tp>
889inline _LIBCPP_INLINE_VISIBILITY
890_Tp
891atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m)
892{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000893 return __o->load(__m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000894}
895
896template <class _Tp>
897inline _LIBCPP_INLINE_VISIBILITY
898_Tp
899atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m)
900{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000901 return __o->load(__m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000902}
903
904// atomic_exchange
905
906template <class _Tp>
907inline _LIBCPP_INLINE_VISIBILITY
908_Tp
909atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d)
910{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000911 return __o->exchange(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000912}
913
914template <class _Tp>
915inline _LIBCPP_INLINE_VISIBILITY
916_Tp
917atomic_exchange(atomic<_Tp>* __o, _Tp __d)
918{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000919 return __o->exchange(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000920}
921
922// atomic_exchange_explicit
923
924template <class _Tp>
925inline _LIBCPP_INLINE_VISIBILITY
926_Tp
927atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m)
928{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000929 return __o->exchange(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000930}
931
932template <class _Tp>
933inline _LIBCPP_INLINE_VISIBILITY
934_Tp
935atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m)
936{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000937 return __o->exchange(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000938}
939
940// atomic_compare_exchange_weak
941
942template <class _Tp>
943inline _LIBCPP_INLINE_VISIBILITY
944bool
945atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d)
946{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000947 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000948}
949
950template <class _Tp>
951inline _LIBCPP_INLINE_VISIBILITY
952bool
953atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d)
954{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000955 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000956}
957
958// atomic_compare_exchange_strong
959
960template <class _Tp>
961inline _LIBCPP_INLINE_VISIBILITY
962bool
963atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d)
964{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000965 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000966}
967
968template <class _Tp>
969inline _LIBCPP_INLINE_VISIBILITY
970bool
971atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d)
972{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000973 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000974}
975
976// atomic_compare_exchange_weak_explicit
977
978template <class _Tp>
979inline _LIBCPP_INLINE_VISIBILITY
980bool
981atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
982 _Tp __d,
983 memory_order __s, memory_order __f)
984{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000985 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000986}
987
988template <class _Tp>
989inline _LIBCPP_INLINE_VISIBILITY
990bool
991atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
992 memory_order __s, memory_order __f)
993{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000994 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000995}
996
997// atomic_compare_exchange_strong_explicit
998
999template <class _Tp>
1000inline _LIBCPP_INLINE_VISIBILITY
1001bool
1002atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1003 _Tp* __e, _Tp __d,
1004 memory_order __s, memory_order __f)
1005{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001006 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001007}
1008
1009template <class _Tp>
1010inline _LIBCPP_INLINE_VISIBILITY
1011bool
1012atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1013 _Tp __d,
1014 memory_order __s, memory_order __f)
1015{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001016 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001017}
1018
Howard Hinnant91e2f262010-12-07 20:46:14 +00001019// atomic_fetch_add
Howard Hinnant4777bf22010-12-06 23:10:08 +00001020
1021template <class _Tp>
Howard Hinnant91e2f262010-12-07 20:46:14 +00001022inline _LIBCPP_INLINE_VISIBILITY
1023typename enable_if
1024<
1025 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1026 _Tp
1027>::type
1028atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op)
Howard Hinnant4777bf22010-12-06 23:10:08 +00001029{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001030 return __o->fetch_add(__op);
1031}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001032
Howard Hinnant91e2f262010-12-07 20:46:14 +00001033template <class _Tp>
1034inline _LIBCPP_INLINE_VISIBILITY
1035typename enable_if
1036<
1037 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1038 _Tp
1039>::type
1040atomic_fetch_add(atomic<_Tp>* __o, _Tp __op)
1041{
1042 return __o->fetch_add(__op);
1043}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001044
Howard Hinnant91e2f262010-12-07 20:46:14 +00001045template <class _Tp>
1046inline _LIBCPP_INLINE_VISIBILITY
1047_Tp*
1048atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op)
1049{
1050 return __o->fetch_add(__op);
1051}
1052
1053template <class _Tp>
1054inline _LIBCPP_INLINE_VISIBILITY
1055_Tp*
1056atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op)
1057{
1058 return __o->fetch_add(__op);
1059}
1060
1061// atomic_fetch_add_explicit
1062
1063template <class _Tp>
1064inline _LIBCPP_INLINE_VISIBILITY
1065typename enable_if
1066<
1067 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1068 _Tp
1069>::type
1070atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1071{
1072 return __o->fetch_add(__op, __m);
1073}
1074
1075template <class _Tp>
1076inline _LIBCPP_INLINE_VISIBILITY
1077typename enable_if
1078<
1079 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1080 _Tp
1081>::type
1082atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1083{
1084 return __o->fetch_add(__op, __m);
1085}
1086
1087template <class _Tp>
1088inline _LIBCPP_INLINE_VISIBILITY
1089_Tp*
1090atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1091 memory_order __m)
1092{
1093 return __o->fetch_add(__op, __m);
1094}
1095
1096template <class _Tp>
1097inline _LIBCPP_INLINE_VISIBILITY
1098_Tp*
1099atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m)
1100{
1101 return __o->fetch_add(__op, __m);
1102}
1103
1104// atomic_fetch_sub
1105
1106template <class _Tp>
1107inline _LIBCPP_INLINE_VISIBILITY
1108typename enable_if
1109<
1110 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1111 _Tp
1112>::type
1113atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op)
1114{
1115 return __o->fetch_sub(__op);
1116}
1117
1118template <class _Tp>
1119inline _LIBCPP_INLINE_VISIBILITY
1120typename enable_if
1121<
1122 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1123 _Tp
1124>::type
1125atomic_fetch_sub(atomic<_Tp>* __o, _Tp __op)
1126{
1127 return __o->fetch_sub(__op);
1128}
1129
1130template <class _Tp>
1131inline _LIBCPP_INLINE_VISIBILITY
1132_Tp*
1133atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op)
1134{
1135 return __o->fetch_sub(__op);
1136}
1137
1138template <class _Tp>
1139inline _LIBCPP_INLINE_VISIBILITY
1140_Tp*
1141atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op)
1142{
1143 return __o->fetch_sub(__op);
1144}
1145
1146// atomic_fetch_sub_explicit
1147
1148template <class _Tp>
1149inline _LIBCPP_INLINE_VISIBILITY
1150typename enable_if
1151<
1152 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1153 _Tp
1154>::type
1155atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1156{
1157 return __o->fetch_sub(__op, __m);
1158}
1159
1160template <class _Tp>
1161inline _LIBCPP_INLINE_VISIBILITY
1162typename enable_if
1163<
1164 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1165 _Tp
1166>::type
1167atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1168{
1169 return __o->fetch_sub(__op, __m);
1170}
1171
1172template <class _Tp>
1173inline _LIBCPP_INLINE_VISIBILITY
1174_Tp*
1175atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1176 memory_order __m)
1177{
1178 return __o->fetch_sub(__op, __m);
1179}
1180
1181template <class _Tp>
1182inline _LIBCPP_INLINE_VISIBILITY
1183_Tp*
1184atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m)
1185{
1186 return __o->fetch_sub(__op, __m);
1187}
1188
1189// atomic_fetch_and
1190
1191template <class _Tp>
1192inline _LIBCPP_INLINE_VISIBILITY
1193typename enable_if
1194<
1195 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1196 _Tp
1197>::type
1198atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op)
1199{
1200 return __o->fetch_and(__op);
1201}
1202
1203template <class _Tp>
1204inline _LIBCPP_INLINE_VISIBILITY
1205typename enable_if
1206<
1207 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1208 _Tp
1209>::type
1210atomic_fetch_and(atomic<_Tp>* __o, _Tp __op)
1211{
1212 return __o->fetch_and(__op);
1213}
1214
1215// atomic_fetch_and_explicit
1216
1217template <class _Tp>
1218inline _LIBCPP_INLINE_VISIBILITY
1219typename enable_if
1220<
1221 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1222 _Tp
1223>::type
1224atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1225{
1226 return __o->fetch_and(__op, __m);
1227}
1228
1229template <class _Tp>
1230inline _LIBCPP_INLINE_VISIBILITY
1231typename enable_if
1232<
1233 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1234 _Tp
1235>::type
1236atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1237{
1238 return __o->fetch_and(__op, __m);
1239}
1240
1241// atomic_fetch_or
1242
1243template <class _Tp>
1244inline _LIBCPP_INLINE_VISIBILITY
1245typename enable_if
1246<
1247 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1248 _Tp
1249>::type
1250atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op)
1251{
1252 return __o->fetch_or(__op);
1253}
1254
1255template <class _Tp>
1256inline _LIBCPP_INLINE_VISIBILITY
1257typename enable_if
1258<
1259 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1260 _Tp
1261>::type
1262atomic_fetch_or(atomic<_Tp>* __o, _Tp __op)
1263{
1264 return __o->fetch_or(__op);
1265}
1266
1267// atomic_fetch_or_explicit
1268
1269template <class _Tp>
1270inline _LIBCPP_INLINE_VISIBILITY
1271typename enable_if
1272<
1273 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1274 _Tp
1275>::type
1276atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1277{
1278 return __o->fetch_or(__op, __m);
1279}
1280
1281template <class _Tp>
1282inline _LIBCPP_INLINE_VISIBILITY
1283typename enable_if
1284<
1285 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1286 _Tp
1287>::type
1288atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1289{
1290 return __o->fetch_or(__op, __m);
1291}
1292
1293// atomic_fetch_xor
1294
1295template <class _Tp>
1296inline _LIBCPP_INLINE_VISIBILITY
1297typename enable_if
1298<
1299 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1300 _Tp
1301>::type
1302atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op)
1303{
1304 return __o->fetch_xor(__op);
1305}
1306
1307template <class _Tp>
1308inline _LIBCPP_INLINE_VISIBILITY
1309typename enable_if
1310<
1311 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1312 _Tp
1313>::type
1314atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op)
1315{
1316 return __o->fetch_xor(__op);
1317}
1318
1319// atomic_fetch_xor_explicit
1320
1321template <class _Tp>
1322inline _LIBCPP_INLINE_VISIBILITY
1323typename enable_if
1324<
1325 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1326 _Tp
1327>::type
1328atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1329{
1330 return __o->fetch_xor(__op, __m);
1331}
1332
1333template <class _Tp>
1334inline _LIBCPP_INLINE_VISIBILITY
1335typename enable_if
1336<
1337 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1338 _Tp
1339>::type
1340atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1341{
1342 return __o->fetch_xor(__op, __m);
1343}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001344
Howard Hinnant770d1c42010-12-08 17:20:28 +00001345// flag type and operations
1346
1347typedef struct atomic_flag
1348{
1349 bool __a_;
1350
1351 _LIBCPP_INLINE_VISIBILITY
1352 bool test_and_set(memory_order __m = memory_order_seq_cst) volatile
1353 {return __atomic_exchange(&__a_, true, __m);}
1354 _LIBCPP_INLINE_VISIBILITY
1355 bool test_and_set(memory_order __m = memory_order_seq_cst)
1356 {return __atomic_exchange(&__a_, true, __m);}
1357 _LIBCPP_INLINE_VISIBILITY
1358 void clear(memory_order __m = memory_order_seq_cst) volatile
1359 {__atomic_store(&__a_, false, __m);}
1360 _LIBCPP_INLINE_VISIBILITY
1361 void clear(memory_order __m = memory_order_seq_cst)
1362 {__atomic_store(&__a_, false, __m);}
1363
1364 _LIBCPP_INLINE_VISIBILITY
1365 atomic_flag() {} // = default;
1366 _LIBCPP_INLINE_VISIBILITY
1367 atomic_flag(bool __b) : __a_(__b) {}
1368
1369#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1370 atomic_flag(const atomic_flag&) = delete;
1371 atomic_flag& operator=(const atomic_flag&) = delete;
1372 atomic_flag& operator=(const atomic_flag&) volatile = delete;
1373#else // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1374private:
1375 atomic_flag(const atomic_flag&);
1376 atomic_flag& operator=(const atomic_flag&);
1377 atomic_flag& operator=(const atomic_flag&) volatile;
1378#endif // _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1379} atomic_flag;
1380
1381inline _LIBCPP_INLINE_VISIBILITY
1382bool
1383atomic_flag_test_and_set(volatile atomic_flag* __o)
1384{
1385 return __o->test_and_set();
1386}
1387
1388inline _LIBCPP_INLINE_VISIBILITY
1389bool
1390atomic_flag_test_and_set(atomic_flag* __o)
1391{
1392 return __o->test_and_set();
1393}
1394
1395inline _LIBCPP_INLINE_VISIBILITY
1396bool
1397atomic_flag_test_and_set_explicit(volatile atomic_flag* __o, memory_order __m)
1398{
1399 return __o->test_and_set(__m);
1400}
1401
1402inline _LIBCPP_INLINE_VISIBILITY
1403bool
1404atomic_flag_test_and_set_explicit(atomic_flag* __o, memory_order __m)
1405{
1406 return __o->test_and_set(__m);
1407}
1408
1409inline _LIBCPP_INLINE_VISIBILITY
1410void
1411atomic_flag_clear(volatile atomic_flag* __o)
1412{
1413 __o->clear();
1414}
1415
1416inline _LIBCPP_INLINE_VISIBILITY
1417void
1418atomic_flag_clear(atomic_flag* __o)
1419{
1420 __o->clear();
1421}
1422
1423inline _LIBCPP_INLINE_VISIBILITY
1424void
1425atomic_flag_clear_explicit(volatile atomic_flag* __o, memory_order __m)
1426{
1427 __o->clear(__m);
1428}
1429
1430inline _LIBCPP_INLINE_VISIBILITY
1431void
1432atomic_flag_clear_explicit(atomic_flag* __o, memory_order __m)
1433{
1434 __o->clear(__m);
1435}
1436
1437// fences
1438
1439inline _LIBCPP_INLINE_VISIBILITY
1440void
1441atomic_thread_fence(memory_order __m)
1442{
1443 __atomic_thread_fence(__m);
1444}
1445
1446inline _LIBCPP_INLINE_VISIBILITY
1447void
1448atomic_signal_fence(memory_order __m)
1449{
1450 __atomic_signal_fence(__m);
1451}
1452
Howard Hinnantd2f6afb2010-12-07 23:24:41 +00001453// Atomics for standard typedef types
1454
1455typedef atomic<char> atomic_char;
1456typedef atomic<signed char> atomic_schar;
1457typedef atomic<unsigned char> atomic_uchar;
1458typedef atomic<short> atomic_short;
1459typedef atomic<unsigned short> atomic_ushort;
1460typedef atomic<int> atomic_int;
1461typedef atomic<unsigned int> atomic_uint;
1462typedef atomic<long> atomic_long;
1463typedef atomic<unsigned long> atomic_ulong;
1464typedef atomic<long long> atomic_llong;
1465typedef atomic<unsigned long long> atomic_ullong;
1466typedef atomic<char16_t> atomic_char16_t;
1467typedef atomic<char32_t> atomic_char32_t;
1468typedef atomic<wchar_t> atomic_wchar_t;
1469
1470typedef atomic<int_least8_t> atomic_int_least8_t;
1471typedef atomic<uint_least8_t> atomic_uint_least8_t;
1472typedef atomic<int_least16_t> atomic_int_least16_t;
1473typedef atomic<uint_least16_t> atomic_uint_least16_t;
1474typedef atomic<int_least32_t> atomic_int_least32_t;
1475typedef atomic<uint_least32_t> atomic_uint_least32_t;
1476typedef atomic<int_least64_t> atomic_int_least64_t;
1477typedef atomic<uint_least64_t> atomic_uint_least64_t;
1478
1479typedef atomic<int_fast8_t> atomic_int_fast8_t;
1480typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1481typedef atomic<int_fast16_t> atomic_int_fast16_t;
1482typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1483typedef atomic<int_fast32_t> atomic_int_fast32_t;
1484typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1485typedef atomic<int_fast64_t> atomic_int_fast64_t;
1486typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1487
1488typedef atomic<intptr_t> atomic_intptr_t;
1489typedef atomic<uintptr_t> atomic_uintptr_t;
1490typedef atomic<size_t> atomic_size_t;
1491typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1492typedef atomic<intmax_t> atomic_intmax_t;
1493typedef atomic<uintmax_t> atomic_uintmax_t;
1494
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001495#define ATOMIC_FLAG_INIT {false}
Howard Hinnant611fdaf2010-10-04 18:52:54 +00001496#define ATOMIC_VAR_INIT(__v) {__v}
1497
Howard Hinnant770d1c42010-12-08 17:20:28 +00001498// lock-free property
Howard Hinnant611fdaf2010-10-04 18:52:54 +00001499
Howard Hinnant770d1c42010-12-08 17:20:28 +00001500#define ATOMIC_CHAR_LOCK_FREE 0
1501#define ATOMIC_CHAR16_T_LOCK_FREE 0
1502#define ATOMIC_CHAR32_T_LOCK_FREE 0
1503#define ATOMIC_WCHAR_T_LOCK_FREE 0
1504#define ATOMIC_SHORT_LOCK_FREE 0
1505#define ATOMIC_INT_LOCK_FREE 0
1506#define ATOMIC_LONG_LOCK_FREE 0
1507#define ATOMIC_LLONG_LOCK_FREE 0
1508
Howard Hinnant154002b2011-03-31 16:39:39 +00001509#endif // !__has_feature(cxx_atomic)
1510
Howard Hinnant8f73c632010-09-27 21:17:38 +00001511_LIBCPP_END_NAMESPACE_STD
1512
1513#endif // _LIBCPP_ATOMIC