blob: 2eee3bd3abc2a2c7ce7253bf3815c49c8e77e45f [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
Howard Hinnant4777bf22010-12-06 23:10:08 +0000531//// Begin Temporary Intrinsics ////
532
533template <class _Tp>
534inline _LIBCPP_INLINE_VISIBILITY
535bool
536__atomic_is_lock_free(_Tp)
537{
538 return false;
539}
540
541template <class _Tp>
542inline _LIBCPP_INLINE_VISIBILITY
543_Tp
544__atomic_load(const volatile _Tp* __t, int)
545{
546 return *__t;
547}
548
549template <class _Tp>
550inline _LIBCPP_INLINE_VISIBILITY
551void
552__atomic_store(volatile _Tp* __t, _Tp __d, int)
553{
554 *__t = __d;
555}
556
557template <class _Tp>
558inline _LIBCPP_INLINE_VISIBILITY
559_Tp
560__atomic_exchange(volatile _Tp* __t, _Tp __d, int)
561{
562 _Tp __tmp = *__t;
563 *__t = __d;
564 return __tmp;
565}
566
567template <class _Tp>
568inline _LIBCPP_INLINE_VISIBILITY
569bool
570__atomic_compare_exchange_strong(volatile _Tp* __o, _Tp* __e, _Tp __d, int, int)
571{
572 if (const_cast<_Tp&>(*__o) == *__e)
573 {
574 *__o = __d;
575 return true;
576 }
577 *__e = __d;
578 return false;
579}
580
581template <class _Tp>
582inline _LIBCPP_INLINE_VISIBILITY
583bool
584__atomic_compare_exchange_weak(volatile _Tp* __o, _Tp* __e, _Tp __d, int, int)
585{
586 if (const_cast<_Tp&>(*__o) == *__e)
587 {
588 *__o = __d;
589 return true;
590 }
591 *__e = __d;
592 return false;
593}
594
Howard Hinnant91e2f262010-12-07 20:46:14 +0000595template <class _Tp>
596inline _LIBCPP_INLINE_VISIBILITY
597_Tp
598__atomic_fetch_add(volatile _Tp* __o, _Tp __op, int)
599{
600 _Tp __tmp = *__o;
601 *__o += __op;
602 return __tmp;
603}
604
605template <class _Tp>
606inline _LIBCPP_INLINE_VISIBILITY
607_Tp*
608__atomic_fetch_add(_Tp* volatile* __o, ptrdiff_t __op, int)
609{
610 _Tp* __tmp = *__o;
611 *__o += __op;
612 return __tmp;
613}
614
615template <class _Tp>
616inline _LIBCPP_INLINE_VISIBILITY
617_Tp
618__atomic_fetch_sub(volatile _Tp* __o, _Tp __op, int)
619{
620 _Tp __tmp = *__o;
621 *__o -= __op;
622 return __tmp;
623}
624
625template <class _Tp>
626inline _LIBCPP_INLINE_VISIBILITY
627_Tp*
628__atomic_fetch_sub(_Tp* volatile* __o, ptrdiff_t __op, int)
629{
630 _Tp* __tmp = *__o;
631 *__o -= __op;
632 return __tmp;
633}
634
635template <class _Tp>
636inline _LIBCPP_INLINE_VISIBILITY
637_Tp
638__atomic_fetch_and(volatile _Tp* __o, _Tp __op, int)
639{
640 _Tp __tmp = *__o;
641 *__o &= __op;
642 return __tmp;
643}
644
645template <class _Tp>
646inline _LIBCPP_INLINE_VISIBILITY
647_Tp
648__atomic_fetch_or(volatile _Tp* __o, _Tp __op, int)
649{
650 _Tp __tmp = *__o;
651 *__o |= __op;
652 return __tmp;
653}
654
655template <class _Tp>
656inline _LIBCPP_INLINE_VISIBILITY
657_Tp
658__atomic_fetch_xor(volatile _Tp* __o, _Tp __op, int)
659{
660 _Tp __tmp = *__o;
661 *__o ^= __op;
662 return __tmp;
663}
664
Howard Hinnant4777bf22010-12-06 23:10:08 +0000665//// End Temporary Intrinsics ////
666
Howard Hinnant8f73c632010-09-27 21:17:38 +0000667_LIBCPP_BEGIN_NAMESPACE_STD
668
Howard Hinnantd1176e22010-09-28 17:13:38 +0000669typedef enum memory_order
670{
671 memory_order_relaxed, memory_order_consume, memory_order_acquire,
672 memory_order_release, memory_order_acq_rel, memory_order_seq_cst
673} memory_order;
674
675template <class _Tp>
676inline _LIBCPP_INLINE_VISIBILITY
677_Tp
678kill_dependency(_Tp __y)
679{
680 return __y;
681}
Howard Hinnant8f73c632010-09-27 21:17:38 +0000682
Howard Hinnant91e2f262010-12-07 20:46:14 +0000683// general atomic<T>
684
685template <class _Tp, bool = is_integral<_Tp>::value && !is_same<_Tp, bool>::value>
686struct __atomic_base // false
687{
688 _Tp __a_;
689
690 _LIBCPP_INLINE_VISIBILITY
691 bool is_lock_free() const volatile
692 {return __atomic_is_lock_free(_Tp());}
693 _LIBCPP_INLINE_VISIBILITY
694 bool is_lock_free() const
695 {return __atomic_is_lock_free(_Tp());}
696 _LIBCPP_INLINE_VISIBILITY
697 void store(_Tp __d, memory_order __m = memory_order_seq_cst) volatile
698 {__atomic_store(&__a_, __d, __m);}
699 _LIBCPP_INLINE_VISIBILITY
700 void store(_Tp __d, memory_order __m = memory_order_seq_cst)
701 {__atomic_store(&__a_, __d, __m);}
702 _LIBCPP_INLINE_VISIBILITY
703 _Tp load(memory_order __m = memory_order_seq_cst) const volatile
704 {return __atomic_load(&__a_, __m);}
705 _LIBCPP_INLINE_VISIBILITY
706 _Tp load(memory_order __m = memory_order_seq_cst) const
707 {return __atomic_load(&__a_, __m);}
708 _LIBCPP_INLINE_VISIBILITY
709 operator _Tp() const volatile {return load();}
710 _LIBCPP_INLINE_VISIBILITY
711 operator _Tp() const {return load();}
712 _LIBCPP_INLINE_VISIBILITY
713 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst) volatile
714 {return __atomic_exchange(&__a_, __d, __m);}
715 _LIBCPP_INLINE_VISIBILITY
716 _Tp exchange(_Tp __d, memory_order __m = memory_order_seq_cst)
717 {return __atomic_exchange(&__a_, __d, __m);}
718 _LIBCPP_INLINE_VISIBILITY
719 bool compare_exchange_weak(_Tp& __e, _Tp __d,
720 memory_order __s, memory_order __f) volatile
721 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
722 _LIBCPP_INLINE_VISIBILITY
723 bool compare_exchange_weak(_Tp& __e, _Tp __d,
724 memory_order __s, memory_order __f)
725 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __s, __f);}
726 _LIBCPP_INLINE_VISIBILITY
727 bool compare_exchange_strong(_Tp& __e, _Tp __d,
728 memory_order __s, memory_order __f) volatile
729 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
730 _LIBCPP_INLINE_VISIBILITY
731 bool compare_exchange_strong(_Tp& __e, _Tp __d,
732 memory_order __s, memory_order __f)
733 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __s, __f);}
734 _LIBCPP_INLINE_VISIBILITY
735 bool compare_exchange_weak(_Tp& __e, _Tp __d,
736 memory_order __m = memory_order_seq_cst) volatile
737 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
738 _LIBCPP_INLINE_VISIBILITY
739 bool compare_exchange_weak(_Tp& __e, _Tp __d,
740 memory_order __m = memory_order_seq_cst)
741 {return __atomic_compare_exchange_weak(&__a_, &__e, __d, __m, __m);}
742 _LIBCPP_INLINE_VISIBILITY
743 bool compare_exchange_strong(_Tp& __e, _Tp __d,
744 memory_order __m = memory_order_seq_cst) volatile
745 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
746 _LIBCPP_INLINE_VISIBILITY
747 bool compare_exchange_strong(_Tp& __e, _Tp __d,
748 memory_order __m = memory_order_seq_cst)
749 {return __atomic_compare_exchange_strong(&__a_, &__e, __d, __m, __m);}
750
751 _LIBCPP_INLINE_VISIBILITY
752 __atomic_base() {} // = default;
753 _LIBCPP_INLINE_VISIBILITY
754 /*constexpr*/ __atomic_base(_Tp __d) : __a_(__d) {}
755 __atomic_base(const __atomic_base&) = delete;
756 __atomic_base& operator=(const __atomic_base&) = delete;
757 __atomic_base& operator=(const __atomic_base&) volatile = delete;
Howard Hinnant91e2f262010-12-07 20:46:14 +0000758};
759
760// atomic<Integral>
761
762template <class _Tp>
763struct __atomic_base<_Tp, true>
764 : public __atomic_base<_Tp, false>
765{
766 typedef __atomic_base<_Tp, false> __base;
767 _LIBCPP_INLINE_VISIBILITY
768 __atomic_base() {} // = default;
769 _LIBCPP_INLINE_VISIBILITY
770 /*constexpr*/ __atomic_base(_Tp __d) : __base(__d) {}
771
772 _LIBCPP_INLINE_VISIBILITY
773 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
774 {return __atomic_fetch_add(&this->__a_, __op, __m);}
775 _LIBCPP_INLINE_VISIBILITY
776 _Tp fetch_add(_Tp __op, memory_order __m = memory_order_seq_cst)
777 {return __atomic_fetch_add(&this->__a_, __op, __m);}
778 _LIBCPP_INLINE_VISIBILITY
779 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
780 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
781 _LIBCPP_INLINE_VISIBILITY
782 _Tp fetch_sub(_Tp __op, memory_order __m = memory_order_seq_cst)
783 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
784 _LIBCPP_INLINE_VISIBILITY
785 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
786 {return __atomic_fetch_and(&this->__a_, __op, __m);}
787 _LIBCPP_INLINE_VISIBILITY
788 _Tp fetch_and(_Tp __op, memory_order __m = memory_order_seq_cst)
789 {return __atomic_fetch_and(&this->__a_, __op, __m);}
790 _LIBCPP_INLINE_VISIBILITY
791 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
792 {return __atomic_fetch_or(&this->__a_, __op, __m);}
793 _LIBCPP_INLINE_VISIBILITY
794 _Tp fetch_or(_Tp __op, memory_order __m = memory_order_seq_cst)
795 {return __atomic_fetch_or(&this->__a_, __op, __m);}
796 _LIBCPP_INLINE_VISIBILITY
797 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst) volatile
798 {return __atomic_fetch_xor(&this->__a_, __op, __m);}
799 _LIBCPP_INLINE_VISIBILITY
800 _Tp fetch_xor(_Tp __op, memory_order __m = memory_order_seq_cst)
801 {return __atomic_fetch_xor(&this->__a_, __op, __m);}
802
803 _LIBCPP_INLINE_VISIBILITY
804 _Tp operator++(int) volatile {return fetch_add(_Tp(1));}
805 _LIBCPP_INLINE_VISIBILITY
806 _Tp operator++(int) {return fetch_add(_Tp(1));}
807 _LIBCPP_INLINE_VISIBILITY
808 _Tp operator--(int) volatile {return fetch_sub(_Tp(1));}
809 _LIBCPP_INLINE_VISIBILITY
810 _Tp operator--(int) {return fetch_sub(_Tp(1));}
811 _LIBCPP_INLINE_VISIBILITY
812 _Tp operator++() volatile {return fetch_add(_Tp(1)) + _Tp(1);}
813 _LIBCPP_INLINE_VISIBILITY
814 _Tp operator++() {return fetch_add(_Tp(1)) + _Tp(1);}
815 _LIBCPP_INLINE_VISIBILITY
816 _Tp operator--() volatile {return fetch_sub(_Tp(1)) - _Tp(1);}
817 _LIBCPP_INLINE_VISIBILITY
818 _Tp operator--() {return fetch_sub(_Tp(1)) - _Tp(1);}
819 _LIBCPP_INLINE_VISIBILITY
820 _Tp operator+=(_Tp __op) volatile {return fetch_add(__op) + __op;}
821 _LIBCPP_INLINE_VISIBILITY
822 _Tp operator+=(_Tp __op) {return fetch_add(__op) + __op;}
823 _LIBCPP_INLINE_VISIBILITY
824 _Tp operator-=(_Tp __op) volatile {return fetch_sub(__op) - __op;}
825 _LIBCPP_INLINE_VISIBILITY
826 _Tp operator-=(_Tp __op) {return fetch_sub(__op) - __op;}
827 _LIBCPP_INLINE_VISIBILITY
828 _Tp operator&=(_Tp __op) volatile {return fetch_and(__op) & __op;}
829 _LIBCPP_INLINE_VISIBILITY
830 _Tp operator&=(_Tp __op) {return fetch_and(__op) & __op;}
831 _LIBCPP_INLINE_VISIBILITY
832 _Tp operator|=(_Tp __op) volatile {return fetch_or(__op) | __op;}
833 _LIBCPP_INLINE_VISIBILITY
834 _Tp operator|=(_Tp __op) {return fetch_or(__op) | __op;}
835 _LIBCPP_INLINE_VISIBILITY
836 _Tp operator^=(_Tp __op) volatile {return fetch_xor(__op) ^ __op;}
837 _LIBCPP_INLINE_VISIBILITY
838 _Tp operator^=(_Tp __op) {return fetch_xor(__op) ^ __op;}
839};
840
841// atomic<T>
842
843template <class _Tp>
844struct atomic
845 : public __atomic_base<_Tp>
846{
847 typedef __atomic_base<_Tp> __base;
848 _LIBCPP_INLINE_VISIBILITY
849 atomic() {} // = default;
850 _LIBCPP_INLINE_VISIBILITY
851 /*constexpr*/ atomic(_Tp __d) : __base(__d) {}
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000852
853 _LIBCPP_INLINE_VISIBILITY
854 _Tp operator=(_Tp __d) volatile
855 {__base::store(__d); return __d;}
856 _LIBCPP_INLINE_VISIBILITY
857 _Tp operator=(_Tp __d)
858 {__base::store(__d); return __d;}
Howard Hinnant91e2f262010-12-07 20:46:14 +0000859};
860
861// atomic<T*>
862
863template <class _Tp>
864struct atomic<_Tp*>
865 : public __atomic_base<_Tp*>
866{
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000867 typedef __atomic_base<_Tp*> __base;
Howard Hinnant91e2f262010-12-07 20:46:14 +0000868 _LIBCPP_INLINE_VISIBILITY
869 atomic() {} // = default;
870 _LIBCPP_INLINE_VISIBILITY
871 /*constexpr*/ atomic(_Tp* __d) : __base(__d) {}
872
873 _LIBCPP_INLINE_VISIBILITY
Howard Hinnantd2f6afb2010-12-07 23:24:41 +0000874 _Tp* operator=(_Tp* __d) volatile
875 {__base::store(__d); return __d;}
876 _LIBCPP_INLINE_VISIBILITY
877 _Tp* operator=(_Tp* __d)
878 {__base::store(__d); return __d;}
879
880 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant91e2f262010-12-07 20:46:14 +0000881 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
882 volatile
883 {return __atomic_fetch_add(&this->__a_, __op, __m);}
884 _LIBCPP_INLINE_VISIBILITY
885 _Tp* fetch_add(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
886 {return __atomic_fetch_add(&this->__a_, __op, __m);}
887 _LIBCPP_INLINE_VISIBILITY
888 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
889 volatile
890 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
891 _LIBCPP_INLINE_VISIBILITY
892 _Tp* fetch_sub(ptrdiff_t __op, memory_order __m = memory_order_seq_cst)
893 {return __atomic_fetch_sub(&this->__a_, __op, __m);}
894
895 _LIBCPP_INLINE_VISIBILITY
896 _Tp* operator++(int) volatile {return fetch_add(1);}
897 _LIBCPP_INLINE_VISIBILITY
898 _Tp* operator++(int) {return fetch_add(1);}
899 _LIBCPP_INLINE_VISIBILITY
900 _Tp* operator--(int) volatile {return fetch_sub(1);}
901 _LIBCPP_INLINE_VISIBILITY
902 _Tp* operator--(int) {return fetch_sub(1);}
903 _LIBCPP_INLINE_VISIBILITY
904 _Tp* operator++() volatile {return fetch_add(1) + 1;}
905 _LIBCPP_INLINE_VISIBILITY
906 _Tp* operator++() {return fetch_add(1) + 1;}
907 _LIBCPP_INLINE_VISIBILITY
908 _Tp* operator--() volatile {return fetch_sub(1) - 1;}
909 _LIBCPP_INLINE_VISIBILITY
910 _Tp* operator--() {return fetch_sub(1) - 1;}
911 _LIBCPP_INLINE_VISIBILITY
912 _Tp* operator+=(ptrdiff_t __op) volatile {return fetch_add(__op) + __op;}
913 _LIBCPP_INLINE_VISIBILITY
914 _Tp* operator+=(ptrdiff_t __op) {return fetch_add(__op) + __op;}
915 _LIBCPP_INLINE_VISIBILITY
916 _Tp* operator-=(ptrdiff_t __op) volatile {return fetch_sub(__op) - __op;}
917 _LIBCPP_INLINE_VISIBILITY
918 _Tp* operator-=(ptrdiff_t __op) {return fetch_sub(__op) - __op;}
919};
Howard Hinnant4777bf22010-12-06 23:10:08 +0000920
921// atomic_is_lock_free
922
923template <class _Tp>
924inline _LIBCPP_INLINE_VISIBILITY
925bool
Howard Hinnant91e2f262010-12-07 20:46:14 +0000926atomic_is_lock_free(const volatile atomic<_Tp>* __o)
Howard Hinnant4777bf22010-12-06 23:10:08 +0000927{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000928 return __o->is_lock_free();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000929}
930
931template <class _Tp>
932inline _LIBCPP_INLINE_VISIBILITY
933bool
Howard Hinnant91e2f262010-12-07 20:46:14 +0000934atomic_is_lock_free(const atomic<_Tp>* __o)
Howard Hinnant4777bf22010-12-06 23:10:08 +0000935{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000936 return __o->is_lock_free();
Howard Hinnant4777bf22010-12-06 23:10:08 +0000937}
938
939// atomic_init
940
941template <class _Tp>
942inline _LIBCPP_INLINE_VISIBILITY
943void
944atomic_init(volatile atomic<_Tp>* __o, _Tp __d)
945{
946 __o->__a_ = __d;
947}
948
949template <class _Tp>
950inline _LIBCPP_INLINE_VISIBILITY
951void
952atomic_init(atomic<_Tp>* __o, _Tp __d)
953{
954 __o->__a_ = __d;
955}
956
957// atomic_store
958
959template <class _Tp>
960inline _LIBCPP_INLINE_VISIBILITY
961void
962atomic_store(volatile atomic<_Tp>* __o, _Tp __d)
963{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000964 __o->store(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000965}
966
967template <class _Tp>
968inline _LIBCPP_INLINE_VISIBILITY
969void
970atomic_store(atomic<_Tp>* __o, _Tp __d)
971{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000972 __o->store(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000973}
974
975// atomic_store_explicit
976
977template <class _Tp>
978inline _LIBCPP_INLINE_VISIBILITY
979void
980atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m)
981{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000982 __o->store(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000983}
984
985template <class _Tp>
986inline _LIBCPP_INLINE_VISIBILITY
987void
988atomic_store_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m)
989{
Howard Hinnant91e2f262010-12-07 20:46:14 +0000990 __o->store(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +0000991}
992
993// atomic_load
994
995template <class _Tp>
996inline _LIBCPP_INLINE_VISIBILITY
997_Tp
998atomic_load(const volatile atomic<_Tp>* __o)
999{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001000 return __o->load();
Howard Hinnant4777bf22010-12-06 23:10:08 +00001001}
1002
1003template <class _Tp>
1004inline _LIBCPP_INLINE_VISIBILITY
1005_Tp
1006atomic_load(const atomic<_Tp>* __o)
1007{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001008 return __o->load();
Howard Hinnant4777bf22010-12-06 23:10:08 +00001009}
1010
1011// atomic_load_explicit
1012
1013template <class _Tp>
1014inline _LIBCPP_INLINE_VISIBILITY
1015_Tp
1016atomic_load_explicit(const volatile atomic<_Tp>* __o, memory_order __m)
1017{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001018 return __o->load(__m);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001019}
1020
1021template <class _Tp>
1022inline _LIBCPP_INLINE_VISIBILITY
1023_Tp
1024atomic_load_explicit(const atomic<_Tp>* __o, memory_order __m)
1025{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001026 return __o->load(__m);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001027}
1028
1029// atomic_exchange
1030
1031template <class _Tp>
1032inline _LIBCPP_INLINE_VISIBILITY
1033_Tp
1034atomic_exchange(volatile atomic<_Tp>* __o, _Tp __d)
1035{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001036 return __o->exchange(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001037}
1038
1039template <class _Tp>
1040inline _LIBCPP_INLINE_VISIBILITY
1041_Tp
1042atomic_exchange(atomic<_Tp>* __o, _Tp __d)
1043{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001044 return __o->exchange(__d);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001045}
1046
1047// atomic_exchange_explicit
1048
1049template <class _Tp>
1050inline _LIBCPP_INLINE_VISIBILITY
1051_Tp
1052atomic_exchange_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m)
1053{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001054 return __o->exchange(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001055}
1056
1057template <class _Tp>
1058inline _LIBCPP_INLINE_VISIBILITY
1059_Tp
1060atomic_exchange_explicit(atomic<_Tp>* __o, _Tp __d, memory_order __m)
1061{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001062 return __o->exchange(__d, __m);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001063}
1064
1065// atomic_compare_exchange_weak
1066
1067template <class _Tp>
1068inline _LIBCPP_INLINE_VISIBILITY
1069bool
1070atomic_compare_exchange_weak(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d)
1071{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001072 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001073}
1074
1075template <class _Tp>
1076inline _LIBCPP_INLINE_VISIBILITY
1077bool
1078atomic_compare_exchange_weak(atomic<_Tp>* __o, _Tp* __e, _Tp __d)
1079{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001080 return __o->compare_exchange_weak(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001081}
1082
1083// atomic_compare_exchange_strong
1084
1085template <class _Tp>
1086inline _LIBCPP_INLINE_VISIBILITY
1087bool
1088atomic_compare_exchange_strong(volatile atomic<_Tp>* __o, _Tp* __e, _Tp __d)
1089{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001090 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001091}
1092
1093template <class _Tp>
1094inline _LIBCPP_INLINE_VISIBILITY
1095bool
1096atomic_compare_exchange_strong(atomic<_Tp>* __o, _Tp* __e, _Tp __d)
1097{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001098 return __o->compare_exchange_strong(*__e, __d);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001099}
1100
1101// atomic_compare_exchange_weak_explicit
1102
1103template <class _Tp>
1104inline _LIBCPP_INLINE_VISIBILITY
1105bool
1106atomic_compare_exchange_weak_explicit(volatile atomic<_Tp>* __o, _Tp* __e,
1107 _Tp __d,
1108 memory_order __s, memory_order __f)
1109{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001110 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001111}
1112
1113template <class _Tp>
1114inline _LIBCPP_INLINE_VISIBILITY
1115bool
1116atomic_compare_exchange_weak_explicit(atomic<_Tp>* __o, _Tp* __e, _Tp __d,
1117 memory_order __s, memory_order __f)
1118{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001119 return __o->compare_exchange_weak(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001120}
1121
1122// atomic_compare_exchange_strong_explicit
1123
1124template <class _Tp>
1125inline _LIBCPP_INLINE_VISIBILITY
1126bool
1127atomic_compare_exchange_strong_explicit(volatile atomic<_Tp>* __o,
1128 _Tp* __e, _Tp __d,
1129 memory_order __s, memory_order __f)
1130{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001131 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001132}
1133
1134template <class _Tp>
1135inline _LIBCPP_INLINE_VISIBILITY
1136bool
1137atomic_compare_exchange_strong_explicit(atomic<_Tp>* __o, _Tp* __e,
1138 _Tp __d,
1139 memory_order __s, memory_order __f)
1140{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001141 return __o->compare_exchange_strong(*__e, __d, __s, __f);
Howard Hinnant4777bf22010-12-06 23:10:08 +00001142}
1143
Howard Hinnant91e2f262010-12-07 20:46:14 +00001144// atomic_fetch_add
Howard Hinnant4777bf22010-12-06 23:10:08 +00001145
1146template <class _Tp>
Howard Hinnant91e2f262010-12-07 20:46:14 +00001147inline _LIBCPP_INLINE_VISIBILITY
1148typename enable_if
1149<
1150 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1151 _Tp
1152>::type
1153atomic_fetch_add(volatile atomic<_Tp>* __o, _Tp __op)
Howard Hinnant4777bf22010-12-06 23:10:08 +00001154{
Howard Hinnant91e2f262010-12-07 20:46:14 +00001155 return __o->fetch_add(__op);
1156}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001157
Howard Hinnant91e2f262010-12-07 20:46:14 +00001158template <class _Tp>
1159inline _LIBCPP_INLINE_VISIBILITY
1160typename enable_if
1161<
1162 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1163 _Tp
1164>::type
1165atomic_fetch_add(atomic<_Tp>* __o, _Tp __op)
1166{
1167 return __o->fetch_add(__op);
1168}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001169
Howard Hinnant91e2f262010-12-07 20:46:14 +00001170template <class _Tp>
1171inline _LIBCPP_INLINE_VISIBILITY
1172_Tp*
1173atomic_fetch_add(volatile atomic<_Tp*>* __o, ptrdiff_t __op)
1174{
1175 return __o->fetch_add(__op);
1176}
1177
1178template <class _Tp>
1179inline _LIBCPP_INLINE_VISIBILITY
1180_Tp*
1181atomic_fetch_add(atomic<_Tp*>* __o, ptrdiff_t __op)
1182{
1183 return __o->fetch_add(__op);
1184}
1185
1186// atomic_fetch_add_explicit
1187
1188template <class _Tp>
1189inline _LIBCPP_INLINE_VISIBILITY
1190typename enable_if
1191<
1192 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1193 _Tp
1194>::type
1195atomic_fetch_add_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1196{
1197 return __o->fetch_add(__op, __m);
1198}
1199
1200template <class _Tp>
1201inline _LIBCPP_INLINE_VISIBILITY
1202typename enable_if
1203<
1204 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1205 _Tp
1206>::type
1207atomic_fetch_add_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1208{
1209 return __o->fetch_add(__op, __m);
1210}
1211
1212template <class _Tp>
1213inline _LIBCPP_INLINE_VISIBILITY
1214_Tp*
1215atomic_fetch_add_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1216 memory_order __m)
1217{
1218 return __o->fetch_add(__op, __m);
1219}
1220
1221template <class _Tp>
1222inline _LIBCPP_INLINE_VISIBILITY
1223_Tp*
1224atomic_fetch_add_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m)
1225{
1226 return __o->fetch_add(__op, __m);
1227}
1228
1229// atomic_fetch_sub
1230
1231template <class _Tp>
1232inline _LIBCPP_INLINE_VISIBILITY
1233typename enable_if
1234<
1235 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1236 _Tp
1237>::type
1238atomic_fetch_sub(volatile atomic<_Tp>* __o, _Tp __op)
1239{
1240 return __o->fetch_sub(__op);
1241}
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_sub(atomic<_Tp>* __o, _Tp __op)
1251{
1252 return __o->fetch_sub(__op);
1253}
1254
1255template <class _Tp>
1256inline _LIBCPP_INLINE_VISIBILITY
1257_Tp*
1258atomic_fetch_sub(volatile atomic<_Tp*>* __o, ptrdiff_t __op)
1259{
1260 return __o->fetch_sub(__op);
1261}
1262
1263template <class _Tp>
1264inline _LIBCPP_INLINE_VISIBILITY
1265_Tp*
1266atomic_fetch_sub(atomic<_Tp*>* __o, ptrdiff_t __op)
1267{
1268 return __o->fetch_sub(__op);
1269}
1270
1271// atomic_fetch_sub_explicit
1272
1273template <class _Tp>
1274inline _LIBCPP_INLINE_VISIBILITY
1275typename enable_if
1276<
1277 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1278 _Tp
1279>::type
1280atomic_fetch_sub_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1281{
1282 return __o->fetch_sub(__op, __m);
1283}
1284
1285template <class _Tp>
1286inline _LIBCPP_INLINE_VISIBILITY
1287typename enable_if
1288<
1289 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1290 _Tp
1291>::type
1292atomic_fetch_sub_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1293{
1294 return __o->fetch_sub(__op, __m);
1295}
1296
1297template <class _Tp>
1298inline _LIBCPP_INLINE_VISIBILITY
1299_Tp*
1300atomic_fetch_sub_explicit(volatile atomic<_Tp*>* __o, ptrdiff_t __op,
1301 memory_order __m)
1302{
1303 return __o->fetch_sub(__op, __m);
1304}
1305
1306template <class _Tp>
1307inline _LIBCPP_INLINE_VISIBILITY
1308_Tp*
1309atomic_fetch_sub_explicit(atomic<_Tp*>* __o, ptrdiff_t __op, memory_order __m)
1310{
1311 return __o->fetch_sub(__op, __m);
1312}
1313
1314// atomic_fetch_and
1315
1316template <class _Tp>
1317inline _LIBCPP_INLINE_VISIBILITY
1318typename enable_if
1319<
1320 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1321 _Tp
1322>::type
1323atomic_fetch_and(volatile atomic<_Tp>* __o, _Tp __op)
1324{
1325 return __o->fetch_and(__op);
1326}
1327
1328template <class _Tp>
1329inline _LIBCPP_INLINE_VISIBILITY
1330typename enable_if
1331<
1332 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1333 _Tp
1334>::type
1335atomic_fetch_and(atomic<_Tp>* __o, _Tp __op)
1336{
1337 return __o->fetch_and(__op);
1338}
1339
1340// atomic_fetch_and_explicit
1341
1342template <class _Tp>
1343inline _LIBCPP_INLINE_VISIBILITY
1344typename enable_if
1345<
1346 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1347 _Tp
1348>::type
1349atomic_fetch_and_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1350{
1351 return __o->fetch_and(__op, __m);
1352}
1353
1354template <class _Tp>
1355inline _LIBCPP_INLINE_VISIBILITY
1356typename enable_if
1357<
1358 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1359 _Tp
1360>::type
1361atomic_fetch_and_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1362{
1363 return __o->fetch_and(__op, __m);
1364}
1365
1366// atomic_fetch_or
1367
1368template <class _Tp>
1369inline _LIBCPP_INLINE_VISIBILITY
1370typename enable_if
1371<
1372 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1373 _Tp
1374>::type
1375atomic_fetch_or(volatile atomic<_Tp>* __o, _Tp __op)
1376{
1377 return __o->fetch_or(__op);
1378}
1379
1380template <class _Tp>
1381inline _LIBCPP_INLINE_VISIBILITY
1382typename enable_if
1383<
1384 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1385 _Tp
1386>::type
1387atomic_fetch_or(atomic<_Tp>* __o, _Tp __op)
1388{
1389 return __o->fetch_or(__op);
1390}
1391
1392// atomic_fetch_or_explicit
1393
1394template <class _Tp>
1395inline _LIBCPP_INLINE_VISIBILITY
1396typename enable_if
1397<
1398 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1399 _Tp
1400>::type
1401atomic_fetch_or_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1402{
1403 return __o->fetch_or(__op, __m);
1404}
1405
1406template <class _Tp>
1407inline _LIBCPP_INLINE_VISIBILITY
1408typename enable_if
1409<
1410 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1411 _Tp
1412>::type
1413atomic_fetch_or_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1414{
1415 return __o->fetch_or(__op, __m);
1416}
1417
1418// atomic_fetch_xor
1419
1420template <class _Tp>
1421inline _LIBCPP_INLINE_VISIBILITY
1422typename enable_if
1423<
1424 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1425 _Tp
1426>::type
1427atomic_fetch_xor(volatile atomic<_Tp>* __o, _Tp __op)
1428{
1429 return __o->fetch_xor(__op);
1430}
1431
1432template <class _Tp>
1433inline _LIBCPP_INLINE_VISIBILITY
1434typename enable_if
1435<
1436 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1437 _Tp
1438>::type
1439atomic_fetch_xor(atomic<_Tp>* __o, _Tp __op)
1440{
1441 return __o->fetch_xor(__op);
1442}
1443
1444// atomic_fetch_xor_explicit
1445
1446template <class _Tp>
1447inline _LIBCPP_INLINE_VISIBILITY
1448typename enable_if
1449<
1450 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1451 _Tp
1452>::type
1453atomic_fetch_xor_explicit(volatile atomic<_Tp>* __o, _Tp __op, memory_order __m)
1454{
1455 return __o->fetch_xor(__op, __m);
1456}
1457
1458template <class _Tp>
1459inline _LIBCPP_INLINE_VISIBILITY
1460typename enable_if
1461<
1462 is_integral<_Tp>::value && !is_same<_Tp, bool>::value,
1463 _Tp
1464>::type
1465atomic_fetch_xor_explicit(atomic<_Tp>* __o, _Tp __op, memory_order __m)
1466{
1467 return __o->fetch_xor(__op, __m);
1468}
Howard Hinnant4777bf22010-12-06 23:10:08 +00001469
Howard Hinnantd2f6afb2010-12-07 23:24:41 +00001470// Atomics for standard typedef types
1471
1472typedef atomic<char> atomic_char;
1473typedef atomic<signed char> atomic_schar;
1474typedef atomic<unsigned char> atomic_uchar;
1475typedef atomic<short> atomic_short;
1476typedef atomic<unsigned short> atomic_ushort;
1477typedef atomic<int> atomic_int;
1478typedef atomic<unsigned int> atomic_uint;
1479typedef atomic<long> atomic_long;
1480typedef atomic<unsigned long> atomic_ulong;
1481typedef atomic<long long> atomic_llong;
1482typedef atomic<unsigned long long> atomic_ullong;
1483typedef atomic<char16_t> atomic_char16_t;
1484typedef atomic<char32_t> atomic_char32_t;
1485typedef atomic<wchar_t> atomic_wchar_t;
1486
1487typedef atomic<int_least8_t> atomic_int_least8_t;
1488typedef atomic<uint_least8_t> atomic_uint_least8_t;
1489typedef atomic<int_least16_t> atomic_int_least16_t;
1490typedef atomic<uint_least16_t> atomic_uint_least16_t;
1491typedef atomic<int_least32_t> atomic_int_least32_t;
1492typedef atomic<uint_least32_t> atomic_uint_least32_t;
1493typedef atomic<int_least64_t> atomic_int_least64_t;
1494typedef atomic<uint_least64_t> atomic_uint_least64_t;
1495
1496typedef atomic<int_fast8_t> atomic_int_fast8_t;
1497typedef atomic<uint_fast8_t> atomic_uint_fast8_t;
1498typedef atomic<int_fast16_t> atomic_int_fast16_t;
1499typedef atomic<uint_fast16_t> atomic_uint_fast16_t;
1500typedef atomic<int_fast32_t> atomic_int_fast32_t;
1501typedef atomic<uint_fast32_t> atomic_uint_fast32_t;
1502typedef atomic<int_fast64_t> atomic_int_fast64_t;
1503typedef atomic<uint_fast64_t> atomic_uint_fast64_t;
1504
1505typedef atomic<intptr_t> atomic_intptr_t;
1506typedef atomic<uintptr_t> atomic_uintptr_t;
1507typedef atomic<size_t> atomic_size_t;
1508typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1509typedef atomic<intmax_t> atomic_intmax_t;
1510typedef atomic<uintmax_t> atomic_uintmax_t;
1511
Howard Hinnant4777bf22010-12-06 23:10:08 +00001512/*
Howard Hinnanted760f42010-09-29 18:13:54 +00001513// flag type and operations
1514
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001515typedef bool __atomic_flag__;
Howard Hinnant6cac2c22010-10-05 14:02:23 +00001516
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001517struct atomic_flag;
Howard Hinnanted760f42010-09-29 18:13:54 +00001518
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001519bool atomic_flag_test_and_set(volatile atomic_flag*);
1520bool atomic_flag_test_and_set(atomic_flag*);
1521bool atomic_flag_test_and_set_explicit(volatile atomic_flag*, memory_order);
1522bool atomic_flag_test_and_set_explicit(atomic_flag*, memory_order);
1523void atomic_flag_clear(volatile atomic_flag*);
1524void atomic_flag_clear(atomic_flag*);
1525void atomic_flag_clear_explicit(volatile atomic_flag*, memory_order);
1526void atomic_flag_clear_explicit(atomic_flag*, memory_order);
1527
1528typedef struct _LIBCPP_VISIBLE atomic_flag
Howard Hinnanted760f42010-09-29 18:13:54 +00001529{
Howard Hinnant6cac2c22010-10-05 14:02:23 +00001530 __atomic_flag__ __flg_;
Howard Hinnanted760f42010-09-29 18:13:54 +00001531
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001532 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001533 bool test_and_set(memory_order __o = memory_order_seq_cst) volatile
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001534 {return atomic_flag_test_and_set_explicit(this, __o);}
1535 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001536 bool test_and_set(memory_order __o = memory_order_seq_cst)
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001537 {return atomic_flag_test_and_set_explicit(this, __o);}
Howard Hinnanted760f42010-09-29 18:13:54 +00001538
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001539 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001540 void clear(memory_order __o = memory_order_seq_cst) volatile
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001541 {atomic_flag_clear_explicit(this, __o);}
1542 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001543 void clear(memory_order __o = memory_order_seq_cst)
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001544 {atomic_flag_clear_explicit(this, __o);}
Howard Hinnanted760f42010-09-29 18:13:54 +00001545
1546#ifndef _LIBCPP_HAS_NO_DEFAULTED_FUNCTIONS
1547 atomic_flag() = default;
1548#else
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001549 _LIBCPP_INLINE_VISIBILITY
Howard Hinnant79101ae2010-09-30 21:05:29 +00001550 atomic_flag() {};
Howard Hinnanted760f42010-09-29 18:13:54 +00001551#endif
1552
Howard Hinnanted760f42010-09-29 18:13:54 +00001553#ifndef _LIBCPP_HAS_NO_DELETED_FUNCTIONS
1554 atomic_flag(const atomic_flag&) = delete;
1555 atomic_flag& operator=(const atomic_flag&) = delete;
1556 atomic_flag& operator=(const atomic_flag&) volatile = delete;
1557#else
1558private:
1559 atomic_flag(const atomic_flag&);
1560 atomic_flag& operator=(const atomic_flag&);
1561 atomic_flag& operator=(const atomic_flag&) volatile;
1562public:
1563#endif
Howard Hinnanted760f42010-09-29 18:13:54 +00001564} atomic_flag;
1565
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001566inline _LIBCPP_INLINE_VISIBILITY
1567bool
1568atomic_flag_test_and_set(volatile atomic_flag* __f)
1569{
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001570 return __atomic_exchange(&__f->__flg_, __atomic_flag__(true),
1571 memory_order_seq_cst)
Howard Hinnant6cac2c22010-10-05 14:02:23 +00001572 == __atomic_flag__(true);
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001573}
Howard Hinnanted760f42010-09-29 18:13:54 +00001574
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001575inline _LIBCPP_INLINE_VISIBILITY
1576bool
1577atomic_flag_test_and_set(atomic_flag* __f)
1578{
1579 return atomic_flag_test_and_set(const_cast<volatile atomic_flag*>(__f));
1580}
1581
1582inline _LIBCPP_INLINE_VISIBILITY
1583bool
1584atomic_flag_test_and_set_explicit(volatile atomic_flag* __f, memory_order __o)
1585{
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001586 return __atomic_exchange(&__f->__flg_, __atomic_flag__(true), __o)
Howard Hinnant6cac2c22010-10-05 14:02:23 +00001587 == __atomic_flag__(true);
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001588}
1589
1590inline _LIBCPP_INLINE_VISIBILITY
1591bool
1592atomic_flag_test_and_set_explicit(atomic_flag* __f, memory_order __o)
1593{
Howard Hinnant611fdaf2010-10-04 18:52:54 +00001594 return atomic_flag_test_and_set_explicit(const_cast<volatile atomic_flag*>
1595 (__f), __o);
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001596}
1597
1598inline _LIBCPP_INLINE_VISIBILITY
1599void
1600atomic_flag_clear(volatile atomic_flag* __f)
1601{
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001602 __atomic_store(&__f->__flg_, __atomic_flag__(false), memory_order_seq_cst);
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001603}
1604
1605inline _LIBCPP_INLINE_VISIBILITY
1606void
1607atomic_flag_clear(atomic_flag* __f)
1608{
1609 atomic_flag_clear(const_cast<volatile atomic_flag*>(__f));
1610}
1611
1612inline _LIBCPP_INLINE_VISIBILITY
1613void
1614atomic_flag_clear_explicit(volatile atomic_flag* __f, memory_order __o)
1615{
Howard Hinnant21ef47f2010-10-18 20:39:07 +00001616 __atomic_store(&__f->__flg_, __atomic_flag__(false), __o);
Howard Hinnant767ae2b2010-09-29 21:20:03 +00001617}
1618
1619inline _LIBCPP_INLINE_VISIBILITY
1620void
1621atomic_flag_clear_explicit(atomic_flag* __f, memory_order __o)
1622{
1623 atomic_flag_clear_explicit(const_cast<volatile atomic_flag*>(__f), __o);
1624}
1625
1626#define ATOMIC_FLAG_INIT {false}
Howard Hinnant611fdaf2010-10-04 18:52:54 +00001627#define ATOMIC_VAR_INIT(__v) {__v}
1628
1629inline _LIBCPP_INLINE_VISIBILITY
1630memory_order
1631__translate_memory_order(memory_order __o)
1632{
1633 switch (__o)
1634 {
1635 case memory_order_acq_rel:
1636 return memory_order_acquire;
1637 case memory_order_release:
1638 return memory_order_relaxed;
1639 }
1640 return __o;
1641}
1642
Howard Hinnant4777bf22010-12-06 23:10:08 +00001643*/
Howard Hinnant8f73c632010-09-27 21:17:38 +00001644_LIBCPP_END_NAMESPACE_STD
1645
1646#endif // _LIBCPP_ATOMIC