2 This file is a part of libcds - Concurrent Data Structures library
4 (C) Copyright Maxim Khizhinsky (libcds.dev@gmail.com) 2006-2016
6 Source code repo: http://github.com/khizmax/libcds/
7 Download: http://sourceforge.net/projects/libcds/files/
9 Redistribution and use in source and binary forms, with or without
10 modification, are permitted provided that the following conditions are met:
12 * Redistributions of source code must retain the above copyright notice, this
13 list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright notice,
16 this list of conditions and the following disclaimer in the documentation
17 and/or other materials provided with the distribution.
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 #ifndef CDSLIB_COMPILER_CXX11_ATOMIC_H
32 #define CDSLIB_COMPILER_CXX11_ATOMIC_H
35 #include <type_traits> // make_unsigned
36 #include <cds/details/defs.h>
37 #include <cds/details/aligned_type.h>
39 namespace cds { namespace cxx11_atomic {
40 typedef enum memory_order {
49 }} // namespace cds::cxx11_atomic
52 #if CDS_COMPILER == CDS_COMPILER_MSVC || (CDS_COMPILER == CDS_COMPILER_INTEL && CDS_OS_INTERFACE == CDS_OSI_WINDOWS)
53 # if CDS_PROCESSOR_ARCH == CDS_PROCESSOR_X86
54 # include <cds/compiler/vc/x86/cxx11_atomic.h>
55 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_AMD64
56 # include <cds/compiler/vc/amd64/cxx11_atomic.h>
58 # error "MS VC++ compiler: unsupported processor architecture"
60 #elif CDS_COMPILER == CDS_COMPILER_GCC || CDS_COMPILER == CDS_COMPILER_CLANG || CDS_COMPILER == CDS_COMPILER_INTEL
61 # if CDS_PROCESSOR_ARCH == CDS_PROCESSOR_X86
62 # include <cds/compiler/gcc/x86/cxx11_atomic.h>
63 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_AMD64
64 # include <cds/compiler/gcc/amd64/cxx11_atomic.h>
65 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_IA64
66 # include <cds/compiler/gcc/ia64/cxx11_atomic.h>
67 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_SPARC
68 # include <cds/compiler/gcc/sparc/cxx11_atomic.h>
69 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_PPC64
70 # include <cds/compiler/gcc/ppc64/cxx11_atomic.h>
71 //# elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_ARM7
72 //# include <cds/compiler/gcc/arm7/cxx11_atomic.h>
74 # error "GCC compiler: unsupported processor architecture. Try to use native C++11 atomic or boost.atomic"
77 # error "Undefined compiler"
80 namespace cds { namespace cxx11_atomic {
82 // forward declarations
88 template <typename T, size_t Size, typename Primary = T >
89 struct atomic_generic_ops;
91 template <typename T, size_t Size>
92 struct atomic_integral_ops;
94 template <size_t TypeSize>
98 struct primary_type<1>
100 typedef std::uint8_t type;
103 struct primary_type<2>
105 typedef std::uint16_t type;
108 struct primary_type<4>
110 typedef std::uint32_t type;
113 struct primary_type<8>
115 typedef std::uint64_t type;
118 template <typename T, typename Primary>
119 struct make_atomic_primary
121 typedef T source_type;
122 typedef Primary primary_type;
124 static primary_type volatile * ptr( source_type volatile * p ) CDS_NOEXCEPT
126 return reinterpret_cast<primary_type volatile *>(p);
128 static primary_type const volatile * ptr( source_type const volatile * p ) CDS_NOEXCEPT
130 return reinterpret_cast<primary_type const volatile *>(p);
133 static primary_type val( source_type v ) CDS_NOEXCEPT
135 return *reinterpret_cast<primary_type*>(&v);
138 static primary_type& ref( source_type& v ) CDS_NOEXCEPT
140 return reinterpret_cast<primary_type&>(v);
143 static primary_type const& ref( source_type const& v ) CDS_NOEXCEPT
145 return reinterpret_cast<primary_type const&>(v);
148 static source_type ret( primary_type r ) CDS_NOEXCEPT
150 return *reinterpret_cast<source_type *>(&r);
154 template <typename T>
155 struct make_atomic_primary<T, T>
157 typedef T source_type;
158 typedef T primary_type;
160 static primary_type volatile * ptr( source_type volatile * p ) CDS_NOEXCEPT
164 static primary_type const volatile * ptr( source_type const volatile * p ) CDS_NOEXCEPT
169 static primary_type val( source_type v ) CDS_NOEXCEPT
174 static primary_type& ref( source_type& v ) CDS_NOEXCEPT
179 static source_type ret( primary_type r ) CDS_NOEXCEPT
185 template <typename T>
186 struct atomic_integral_bitwise_ops
189 typedef typename std::make_unsigned<T>::type unsigned_type;
190 typedef atomic_generic_ops<unsigned_type, sizeof(unsigned_type)> atomic_ops;
192 static T fetch_and(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
194 unsigned_type cur = atomic_ops::atomic_load_explicit( reinterpret_cast<unsigned_type volatile *>(pDest), memory_order_relaxed );
195 do {} while ( !atomic_ops::atomic_compare_exchange_weak_explicit(
196 reinterpret_cast<unsigned_type volatile *>(pDest), &cur, cur & unsigned_type(val), order, memory_order_relaxed ));
200 static T fetch_or(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
202 unsigned_type cur = atomic_ops::atomic_load_explicit( reinterpret_cast<unsigned_type volatile *>(pDest), memory_order_relaxed );
203 do {} while ( !atomic_ops::atomic_compare_exchange_weak_explicit(
204 reinterpret_cast<unsigned_type volatile *>(pDest), &cur, cur | unsigned_type(val), order, memory_order_relaxed ));
208 static T fetch_xor(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
210 unsigned_type cur = atomic_ops::atomic_load_explicit( reinterpret_cast<unsigned_type volatile *>(pDest), memory_order_relaxed );
211 do {} while ( !atomic_ops::atomic_compare_exchange_weak_explicit(
212 reinterpret_cast<unsigned_type volatile *>(pDest), &cur, cur ^ unsigned_type(val), order, memory_order_relaxed ));
218 // 8-bit atomic operations
220 template <typename T, typename Primary>
221 struct atomic_generic_ops< T, 1, Primary >
223 typedef make_atomic_primary<T, Primary> primary;
226 static void atomic_store_explicit( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
228 platform::store8( primary::ptr(pDest), primary::val(v), order );
230 static void atomic_store_explicit( T * pDest, T v, memory_order order ) CDS_NOEXCEPT
232 platform::store8( primary::ptr(pDest), primary::val(v), order );
234 static void atomic_store( T volatile * pDest, T v ) CDS_NOEXCEPT
236 atomic_store_explicit( pDest, v, memory_order_seq_cst );
238 static void atomic_store( T * pDest, T v ) CDS_NOEXCEPT
240 atomic_store_explicit( pDest, v, memory_order_seq_cst );
244 static T atomic_load_explicit( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
246 return primary::ret( platform::load8( primary::ptr(pSrc), order ));
248 static T atomic_load_explicit( T const * pSrc, memory_order order ) CDS_NOEXCEPT
250 return primary::ret( platform::load8( primary::ptr(pSrc), order ));
252 static T atomic_load( T volatile const * pSrc ) CDS_NOEXCEPT
254 return atomic_load_explicit( pSrc, memory_order_seq_cst );
256 static T atomic_load( T const * pSrc ) CDS_NOEXCEPT
258 return atomic_load_explicit( pSrc, memory_order_seq_cst );
262 static T atomic_exchange_explicit( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
264 return primary::ret( platform::exchange8( primary::ptr(pDest), primary::val(val), order ));
266 static T atomic_exchange_explicit( T * pDest, T val, memory_order order ) CDS_NOEXCEPT
268 return primary::ret( platform::exchange8( primary::ptr(pDest), primary::val(val), order ));
270 static T atomic_exchange( T volatile * pDest, T val ) CDS_NOEXCEPT
272 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
274 static T atomic_exchange( T * pDest, T val ) CDS_NOEXCEPT
276 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
280 static bool atomic_compare_exchange_weak_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
283 return platform::cas8_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
285 static bool atomic_compare_exchange_weak_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
288 return platform::cas8_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
290 static bool atomic_compare_exchange_weak( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
292 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
294 static bool atomic_compare_exchange_weak( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
296 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
298 static bool atomic_compare_exchange_strong_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
301 return platform::cas8_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
303 static bool atomic_compare_exchange_strong_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
306 return platform::cas8_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
308 static bool atomic_compare_exchange_strong( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
310 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
312 static bool atomic_compare_exchange_strong( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
314 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
318 template <typename T>
319 struct atomic_integral_ops< T, 1 >
320 : atomic_generic_ops<T, 1, T >
321 , atomic_integral_bitwise_ops<T>
323 typedef atomic_integral_bitwise_ops<T> bitwise_ops;
326 static T atomic_fetch_add_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
328 # ifdef CDS_ATOMIC_fetch8_add_defined
329 return platform::fetch8_add( pDest, val, order );
331 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
332 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
336 static T atomic_fetch_add_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
338 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
340 static T atomic_fetch_add( T volatile * pDest, T val ) CDS_NOEXCEPT
342 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
344 static T atomic_fetch_add( T * pDest, T val ) CDS_NOEXCEPT
346 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
350 static T atomic_fetch_sub_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
352 # ifdef CDS_ATOMIC_fetch8_sub_defined
353 return platform::fetch8_sub( pDest, val, order );
355 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
356 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
360 static T atomic_fetch_sub_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
362 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
364 static T atomic_fetch_sub( T volatile * pDest, T val ) CDS_NOEXCEPT
366 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
368 static T atomic_fetch_sub( T * pDest, T val ) CDS_NOEXCEPT
370 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
374 static T atomic_fetch_and_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
376 # ifdef CDS_ATOMIC_fetch8_and_defined
377 return platform::fetch8_and( pDest, val, order );
379 return bitwise_ops::fetch_and( pDest, val, order );
382 static T atomic_fetch_and_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
384 return atomic_fetch_and_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
386 static T atomic_fetch_and( T volatile * pDest, T val ) CDS_NOEXCEPT
388 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
390 static T atomic_fetch_and( T * pDest, T val ) CDS_NOEXCEPT
392 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
396 static T atomic_fetch_or_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
398 # ifdef CDS_ATOMIC_fetch8_or_defined
399 return platform::fetch8_or( pDest, val, order );
401 return bitwise_ops::fetch_or( pDest, val, order );
404 static T atomic_fetch_or_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
406 return atomic_fetch_or_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
408 static T atomic_fetch_or( T volatile * pDest, T val ) CDS_NOEXCEPT
410 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
412 static T atomic_fetch_or( T * pDest, T val ) CDS_NOEXCEPT
414 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
418 static T atomic_fetch_xor_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
420 # ifdef CDS_ATOMIC_fetch8_xor_defined
421 return platform::fetch8_xor( pDest, val, order );
423 return bitwise_ops::fetch_xor( pDest, val, order );
426 static T atomic_fetch_xor_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
428 return atomic_fetch_xor_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
430 static T atomic_fetch_xor( T volatile * pDest, T val ) CDS_NOEXCEPT
432 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
434 static T atomic_fetch_xor( T * pDest, T val ) CDS_NOEXCEPT
436 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
440 // 16-bit atomic operations
442 template <typename T, typename Primary>
443 struct atomic_generic_ops< T, 2, Primary >
445 typedef make_atomic_primary<T, Primary> primary;
448 static void atomic_store_explicit( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
450 platform::store16( primary::ptr(pDest), primary::val(v), order );
452 static void atomic_store_explicit( T * pDest, T v, memory_order order ) CDS_NOEXCEPT
454 platform::store16( primary::ptr(pDest), primary::val(v), order );
456 static void atomic_store( T volatile * pDest, T v ) CDS_NOEXCEPT
458 atomic_store_explicit( pDest, v, memory_order_seq_cst );
460 static void atomic_store( T * pDest, T v ) CDS_NOEXCEPT
462 atomic_store_explicit( pDest, v, memory_order_seq_cst );
466 static T atomic_load_explicit( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
468 return primary::ret( platform::load16( primary::ptr(pSrc), order ));
470 static T atomic_load_explicit( T const * pSrc, memory_order order ) CDS_NOEXCEPT
472 return primary::ret( platform::load16( primary::ptr(pSrc), order ));
474 static T atomic_load( T volatile const * pSrc ) CDS_NOEXCEPT
476 return atomic_load_explicit( pSrc, memory_order_seq_cst );
478 static T atomic_load( T const * pSrc ) CDS_NOEXCEPT
480 return atomic_load_explicit( pSrc, memory_order_seq_cst );
484 static T atomic_exchange_explicit( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
486 return primary::ret( platform::exchange16( primary::ptr(pDest), primary::val(val), order ));
488 static T atomic_exchange_explicit( T * pDest, T val, memory_order order ) CDS_NOEXCEPT
490 return primary::ret( platform::exchange16( primary::ptr(pDest), primary::val(val), order ));
492 static T atomic_exchange( T volatile * pDest, T val ) CDS_NOEXCEPT
494 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
496 static T atomic_exchange( T * pDest, T val ) CDS_NOEXCEPT
498 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
502 static bool atomic_compare_exchange_weak_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
505 return platform::cas16_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
507 static bool atomic_compare_exchange_weak_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
510 return platform::cas16_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
512 static bool atomic_compare_exchange_weak( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
514 return atomic_compare_exchange_weak_explicit( pDest, expected, primary::val(desired), memory_order_seq_cst, memory_order_relaxed );
516 static bool atomic_compare_exchange_weak( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
518 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
520 static bool atomic_compare_exchange_strong_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
523 return platform::cas16_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
525 static bool atomic_compare_exchange_strong_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
528 return platform::cas16_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
530 static bool atomic_compare_exchange_strong( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
532 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
534 static bool atomic_compare_exchange_strong( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
536 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
540 template <typename T>
541 struct atomic_integral_ops< T, 2 >
542 : atomic_generic_ops< T, 2, T >
543 , atomic_integral_bitwise_ops<T>
545 typedef atomic_integral_bitwise_ops<T> bitwise_ops;
548 static T atomic_fetch_add_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
550 # ifdef CDS_ATOMIC_fetch16_add_defined
551 return platform::fetch16_add( pDest, val, order );
553 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
554 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
558 static T atomic_fetch_add_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
560 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
562 static T atomic_fetch_add( T volatile * pDest, T val ) CDS_NOEXCEPT
564 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
566 static T atomic_fetch_add( T * pDest, T val ) CDS_NOEXCEPT
568 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
572 static T atomic_fetch_sub_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
574 # ifdef CDS_ATOMIC_fetch16_sub_defined
575 return platform::fetch16_sub( pDest, val, order );
577 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
578 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
582 static T atomic_fetch_sub_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
584 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
586 static T atomic_fetch_sub( T volatile * pDest, T val ) CDS_NOEXCEPT
588 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
590 static T atomic_fetch_sub( T * pDest, T val ) CDS_NOEXCEPT
592 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
596 static T atomic_fetch_and_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
598 # ifdef CDS_ATOMIC_fetch16_and_defined
599 return platform::fetch16_and( pDest, val, order );
601 return bitwise_ops::fetch_and( pDest, val, order );
604 static T atomic_fetch_and_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
606 return atomic_fetch_and_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
608 static T atomic_fetch_and( T volatile * pDest, T val ) CDS_NOEXCEPT
610 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
612 static T atomic_fetch_and( T * pDest, T val ) CDS_NOEXCEPT
614 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
618 static T atomic_fetch_or_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
620 # ifdef CDS_ATOMIC_fetch16_or_defined
621 return platform::fetch16_or( pDest, val, order );
623 return bitwise_ops::fetch_or( pDest, val, order );
626 static T atomic_fetch_or_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
628 return atomic_fetch_or_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
630 static T atomic_fetch_or( T volatile * pDest, T val ) CDS_NOEXCEPT
632 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
634 static T atomic_fetch_or( T * pDest, T val ) CDS_NOEXCEPT
636 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
640 static T atomic_fetch_xor_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
642 # ifdef CDS_ATOMIC_fetch16_xor_defined
643 return platform::fetch16_xor( pDest, val, order );
645 return bitwise_ops::fetch_xor( pDest, val, order );
648 static T atomic_fetch_xor_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
650 return atomic_fetch_xor_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
652 static T atomic_fetch_xor( T volatile * pDest, T val ) CDS_NOEXCEPT
654 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
656 static T atomic_fetch_xor( T * pDest, T val ) CDS_NOEXCEPT
658 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
662 // 32-bit atomic operations
664 template <typename T, typename Primary>
665 struct atomic_generic_ops< T, 4, Primary >
667 typedef make_atomic_primary<T, Primary> primary;
670 static void atomic_store_explicit( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
672 platform::store32( primary::ptr(pDest), primary::val(v), order );
674 static void atomic_store_explicit( T * pDest, T v, memory_order order ) CDS_NOEXCEPT
676 platform::store32( primary::ptr(pDest), primary::val(v), order );
678 static void atomic_store( T volatile * pDest, T v ) CDS_NOEXCEPT
680 atomic_store_explicit( pDest, v, memory_order_seq_cst );
682 static void atomic_store( T * pDest, T v ) CDS_NOEXCEPT
684 atomic_store_explicit( pDest, v, memory_order_seq_cst );
688 static T atomic_load_explicit( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
690 return primary::ret( platform::load32( primary::ptr(pSrc), order ));
692 static T atomic_load_explicit( T const * pSrc, memory_order order ) CDS_NOEXCEPT
694 return primary::ret( platform::load32( primary::ptr(pSrc), order ));
696 static T atomic_load( T volatile const * pSrc ) CDS_NOEXCEPT
698 return atomic_load_explicit( pSrc, memory_order_seq_cst );
700 static T atomic_load( T const * pSrc ) CDS_NOEXCEPT
702 return atomic_load_explicit( pSrc, memory_order_seq_cst );
706 static T atomic_exchange_explicit( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
708 return primary::ret( platform::exchange32( primary::ptr(pDest), primary::val(val), order ));
710 static T atomic_exchange_explicit( T * pDest, T val, memory_order order ) CDS_NOEXCEPT
712 return primary::ret( platform::exchange32( primary::ptr(pDest), primary::val(val), order ));
714 static T atomic_exchange( T volatile * pDest, T val ) CDS_NOEXCEPT
716 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
718 static T atomic_exchange( T * pDest, T val ) CDS_NOEXCEPT
720 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
724 static bool atomic_compare_exchange_weak_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
727 return platform::cas32_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
729 static bool atomic_compare_exchange_weak_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
732 return platform::cas32_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
734 static bool atomic_compare_exchange_weak( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
736 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
738 static bool atomic_compare_exchange_weak( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
740 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
742 static bool atomic_compare_exchange_strong_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
745 return platform::cas32_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
747 static bool atomic_compare_exchange_strong_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
750 return platform::cas32_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
752 static bool atomic_compare_exchange_strong( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
754 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
756 static bool atomic_compare_exchange_strong( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
758 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
762 template <typename T>
763 struct atomic_integral_ops< T, 4 >
764 : atomic_generic_ops< T, 4, T >
765 , atomic_integral_bitwise_ops<T>
767 typedef atomic_integral_bitwise_ops<T> bitwise_ops;
769 static T atomic_fetch_add_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
771 # ifdef CDS_ATOMIC_fetch32_add_defined
772 return platform::fetch32_add( pDest, val, order );
774 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
775 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
779 static T atomic_fetch_add_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
781 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
783 static T atomic_fetch_add( T volatile * pDest, T val ) CDS_NOEXCEPT
785 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
787 static T atomic_fetch_add( T * pDest, T val ) CDS_NOEXCEPT
789 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
793 static T atomic_fetch_sub_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
795 # ifdef CDS_ATOMIC_fetch32_sub_defined
796 return platform::fetch32_sub( pDest, val, order );
798 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
799 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
803 static T atomic_fetch_sub_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
805 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
807 static T atomic_fetch_sub( T volatile * pDest, T val ) CDS_NOEXCEPT
809 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
811 static T atomic_fetch_sub( T * pDest, T val ) CDS_NOEXCEPT
813 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
817 static T atomic_fetch_and_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
819 # ifdef CDS_ATOMIC_fetch32_and_defined
820 return platform::fetch32_and( pDest, val, order );
822 return bitwise_ops::fetch_and( pDest, val, order );
825 static T atomic_fetch_and_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
827 return atomic_fetch_and_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
829 static T atomic_fetch_and( T volatile * pDest, T val ) CDS_NOEXCEPT
831 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
833 static T atomic_fetch_and( T * pDest, T val ) CDS_NOEXCEPT
835 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
839 static T atomic_fetch_or_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
841 # ifdef CDS_ATOMIC_fetch32_or_defined
842 return platform::fetch32_or( pDest, val, order );
844 return bitwise_ops::fetch_or( pDest, val, order );
847 static T atomic_fetch_or_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
849 return atomic_fetch_or_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
851 static T atomic_fetch_or( T volatile * pDest, T val ) CDS_NOEXCEPT
853 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
855 static T atomic_fetch_or( T * pDest, T val ) CDS_NOEXCEPT
857 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
861 static T atomic_fetch_xor_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
863 # ifdef CDS_ATOMIC_fetch32_xor_defined
864 return platform::fetch32_xor( pDest, val, order );
866 return bitwise_ops::fetch_xor( pDest, val, order );
869 static T atomic_fetch_xor_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
871 return atomic_fetch_xor_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
873 static T atomic_fetch_xor( T volatile * pDest, T val ) CDS_NOEXCEPT
875 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
877 static T atomic_fetch_xor( T * pDest, T val ) CDS_NOEXCEPT
879 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
884 // 64-bit atomic operations
886 template <typename T, typename Primary>
887 struct atomic_generic_ops< T, 8, Primary >
889 typedef make_atomic_primary<T, Primary> primary;
892 static void atomic_store_explicit( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
894 platform::store64( primary::ptr(pDest), primary::val(v), order );
896 static void atomic_store_explicit( T * pDest, T v, memory_order order ) CDS_NOEXCEPT
898 platform::store64( primary::ptr(pDest), primary::val(v), order );
900 static void atomic_store( T volatile * pDest, T v ) CDS_NOEXCEPT
902 atomic_store_explicit( pDest, v, memory_order_seq_cst );
904 static void atomic_store( T * pDest, T v ) CDS_NOEXCEPT
906 atomic_store_explicit( pDest, v, memory_order_seq_cst );
910 static T atomic_load_explicit( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
912 return primary::ret( platform::load64( primary::ptr(pSrc), order ));
914 static T atomic_load_explicit( T const * pSrc, memory_order order ) CDS_NOEXCEPT
916 return primary::ret( platform::load64( primary::ptr(pSrc), order ));
918 static T atomic_load( T volatile const * pSrc ) CDS_NOEXCEPT
920 return atomic_load_explicit( pSrc, memory_order_seq_cst );
922 static T atomic_load( T const * pSrc ) CDS_NOEXCEPT
924 return atomic_load_explicit( pSrc, memory_order_seq_cst );
928 static T atomic_exchange_explicit( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
930 return primary::ret( platform::exchange64( primary::ptr(pDest), primary::val(val), order ));
932 static T atomic_exchange_explicit( T * pDest, T val, memory_order order ) CDS_NOEXCEPT
934 return primary::ret( platform::exchange64( primary::ptr(pDest), primary::val(val), order ));
936 static T atomic_exchange( T volatile * pDest, T val ) CDS_NOEXCEPT
938 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
940 static T atomic_exchange( T * pDest, T val ) CDS_NOEXCEPT
942 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
946 static bool atomic_compare_exchange_weak_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
949 return platform::cas64_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
951 static bool atomic_compare_exchange_weak_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
954 return platform::cas64_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
956 static bool atomic_compare_exchange_weak( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
958 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
960 static bool atomic_compare_exchange_weak( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
962 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
964 static bool atomic_compare_exchange_strong_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
967 return platform::cas64_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
969 static bool atomic_compare_exchange_strong_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
972 return platform::cas64_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
974 static bool atomic_compare_exchange_strong( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
976 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
978 static bool atomic_compare_exchange_strong( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
980 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
985 template <typename T>
986 struct atomic_integral_ops< T, 8 >
987 : atomic_generic_ops< T, 8, T >
988 , atomic_integral_bitwise_ops<T>
990 typedef atomic_integral_bitwise_ops<T> bitwise_ops;
991 typedef atomic_generic_ops<T, 8, T> general_ops;
994 static T atomic_fetch_add_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
996 # ifdef CDS_ATOMIC_fetch64_add_defined
997 return platform::fetch64_add( pDest, val, order );
999 T cur = general_ops::atomic_load_explicit( pDest, memory_order_relaxed );
1000 do {} while ( !general_ops::atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
1004 static T atomic_fetch_add_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1006 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1008 static T atomic_fetch_add( T volatile * pDest, T val ) CDS_NOEXCEPT
1010 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1012 static T atomic_fetch_add( T * pDest, T val ) CDS_NOEXCEPT
1014 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1018 static T atomic_fetch_sub_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
1020 # ifdef CDS_ATOMIC_fetch64_sub_defined
1021 return platform::fetch64_sub( pDest, val, order );
1023 T cur = general_ops::atomic_load_explicit( pDest, memory_order_relaxed );
1024 do {} while ( !general_ops::atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
1028 static T atomic_fetch_sub_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1030 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1032 static T atomic_fetch_sub( T volatile * pDest, T val ) CDS_NOEXCEPT
1034 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1036 static T atomic_fetch_sub( T * pDest, T val ) CDS_NOEXCEPT
1038 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1042 static T atomic_fetch_and_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
1044 # ifdef CDS_ATOMIC_fetch64_and_defined
1045 return platform::fetch64_and( pDest, val, order );
1047 return bitwise_ops::fetch_and( pDest, val, order );
1050 static T atomic_fetch_and_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1052 return atomic_fetch_and_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1054 static T atomic_fetch_and( T volatile * pDest, T val ) CDS_NOEXCEPT
1056 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
1058 static T atomic_fetch_and( T * pDest, T val ) CDS_NOEXCEPT
1060 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
1064 static T atomic_fetch_or_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
1066 # ifdef CDS_ATOMIC_fetch64_or_defined
1067 return platform::fetch64_or( pDest, val, order );
1069 return bitwise_ops::fetch_or( pDest, val, order );
1072 static T atomic_fetch_or_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1074 return atomic_fetch_or_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1076 static T atomic_fetch_or( T volatile * pDest, T val ) CDS_NOEXCEPT
1078 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
1080 static T atomic_fetch_or( T * pDest, T val ) CDS_NOEXCEPT
1082 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
1086 static T atomic_fetch_xor_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
1088 # ifdef CDS_ATOMIC_fetch64_xor_defined
1089 return platform::fetch64_xor( pDest, val, order );
1091 return bitwise_ops::fetch_xor( pDest, val, order );
1094 static T atomic_fetch_xor_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1096 return atomic_fetch_xor_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1098 static T atomic_fetch_xor( T volatile * pDest, T val ) CDS_NOEXCEPT
1100 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
1102 static T atomic_fetch_xor( T * pDest, T val ) CDS_NOEXCEPT
1104 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
1109 // atomic pointer operations
1110 template <typename T>
1111 struct atomic_pointer_base
1114 static void atomic_store_explicit( T * volatile * pDest, T * v, memory_order order ) CDS_NOEXCEPT
1116 platform::store_ptr( pDest, v, order );
1118 static void atomic_store_explicit( T * * pDest, T * v, memory_order order ) CDS_NOEXCEPT
1120 platform::store_ptr( pDest, v, order );
1122 static void atomic_store( T * volatile * pDest, T * v ) CDS_NOEXCEPT
1124 atomic_store_explicit( pDest, v, memory_order_seq_cst );
1126 static void atomic_store( T * * pDest, T * v ) CDS_NOEXCEPT
1128 atomic_store_explicit( pDest, v, memory_order_seq_cst );
1132 static T * atomic_load_explicit( T * volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
1134 return platform::load_ptr( pSrc, order );
1136 static T * atomic_load_explicit( T * const * pSrc, memory_order order ) CDS_NOEXCEPT
1138 return platform::load_ptr( pSrc, order );
1140 static T * atomic_load( T * volatile const * pSrc ) CDS_NOEXCEPT
1142 return atomic_load_explicit( pSrc, memory_order_seq_cst );
1144 static T * atomic_load( T * const * pSrc ) CDS_NOEXCEPT
1146 return atomic_load_explicit( pSrc, memory_order_seq_cst );
1150 static T * atomic_exchange_explicit( T * volatile * pDest, T * val, memory_order order ) CDS_NOEXCEPT
1152 return platform::exchange_ptr( pDest, val, order );
1154 static T * atomic_exchange_explicit( T * * pDest, T * val, memory_order order ) CDS_NOEXCEPT
1156 return platform::exchange_ptr( pDest, val, order );
1158 static T * atomic_exchange( T * volatile * pDest, T * val ) CDS_NOEXCEPT
1160 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
1162 static T * atomic_exchange( T * * pDest, T * val ) CDS_NOEXCEPT
1164 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
1168 static bool atomic_compare_exchange_weak_explicit( T * volatile * pDest, T * * expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
1171 return platform::cas_ptr_weak( pDest, *expected, desired, mo_success, mo_fail );
1173 static bool atomic_compare_exchange_weak_explicit( T * * pDest, T * * expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
1176 return platform::cas_ptr_weak( pDest, *expected, desired, mo_success, mo_fail );
1178 static bool atomic_compare_exchange_weak( T * volatile * pDest, T ** expected, T * desired ) CDS_NOEXCEPT
1180 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
1182 static bool atomic_compare_exchange_weak( T ** pDest, T ** expected, T * desired ) CDS_NOEXCEPT
1184 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
1186 static bool atomic_compare_exchange_strong_explicit( T * volatile * pDest, T ** expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
1189 return platform::cas_ptr_strong( pDest, *expected, desired, mo_success, mo_fail );
1191 static bool atomic_compare_exchange_strong_explicit( T ** pDest, T ** expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
1194 return platform::cas_ptr_strong( pDest, *expected, desired, mo_success, mo_fail );
1196 static bool atomic_compare_exchange_strong( T * volatile * pDest, T ** expected, T * desired ) CDS_NOEXCEPT
1198 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
1200 static bool atomic_compare_exchange_strong( T ** pDest, T ** expected, T * desired ) CDS_NOEXCEPT
1202 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
1206 template <typename T>
1207 struct atomic_pointer: public atomic_pointer_base<T>
1209 typedef atomic_pointer_base<T> base_class;
1211 static T * atomic_fetch_add_explicit(T * volatile * pDest, ptrdiff_t val, memory_order order) CDS_NOEXCEPT
1213 # ifdef CDS_ATOMIC_fetch_ptr_add_defined
1214 platform::fetch_ptr_add( pDest, val, order );
1216 T * cur = base_class::atomic_load_explicit( pDest, memory_order_relaxed );
1217 do {} while ( !base_class::atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
1221 static T * atomic_fetch_add_explicit(T * * pDest, ptrdiff_t val , memory_order order) CDS_NOEXCEPT
1223 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1225 static T * atomic_fetch_add( T * volatile * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1227 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1229 static T * atomic_fetch_add( T ** pDest, ptrdiff_t val ) CDS_NOEXCEPT
1231 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1235 static T * atomic_fetch_sub_explicit(T * volatile * pDest, ptrdiff_t val, memory_order order) CDS_NOEXCEPT
1237 # ifdef CDS_ATOMIC_fetch_ptr_sub_defined
1238 platform::fetch_ptr_sub( pDest, val, order );
1240 T * cur = base_class::atomic_load_explicit( pDest, memory_order_relaxed );
1241 do {} while ( !base_class::atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
1245 static T * atomic_fetch_sub_explicit(T ** pDest, ptrdiff_t val , memory_order order) CDS_NOEXCEPT
1247 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1249 static T * atomic_fetch_sub( T volatile * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1251 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1253 static T * atomic_fetch_sub( T * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1255 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1260 struct atomic_pointer<void>: public atomic_pointer_base<void>
1262 typedef atomic_pointer_base<void> base_class;
1265 static void * atomic_fetch_add_explicit(void * volatile * pDest, ptrdiff_t val, memory_order order) CDS_NOEXCEPT
1267 void * cur = base_class::atomic_load_explicit( pDest, memory_order_relaxed );
1268 do {} while ( !base_class::atomic_compare_exchange_weak_explicit( pDest, &cur, reinterpret_cast<char *>(cur) + val, order, memory_order_relaxed ));
1271 static void * atomic_fetch_add_explicit(void * * pDest, ptrdiff_t val , memory_order order) CDS_NOEXCEPT
1273 return atomic_fetch_add_explicit( reinterpret_cast<void * volatile *>( pDest ), val, order );
1275 static void * atomic_fetch_add( void * volatile * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1277 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1279 static void * atomic_fetch_add( void ** pDest, ptrdiff_t val ) CDS_NOEXCEPT
1281 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1285 static void * atomic_fetch_sub_explicit(void * volatile * pDest, ptrdiff_t val, memory_order order) CDS_NOEXCEPT
1287 void * cur = base_class::atomic_load_explicit( pDest, memory_order_relaxed );
1288 do {} while ( !base_class::atomic_compare_exchange_weak_explicit( pDest, &cur, reinterpret_cast<char *>(cur) - val, order, memory_order_relaxed ));
1291 static void * atomic_fetch_sub_explicit(void ** pDest, ptrdiff_t val , memory_order order) CDS_NOEXCEPT
1293 return atomic_fetch_sub_explicit( reinterpret_cast<void * volatile *>( pDest ), val, order );
1295 static void * atomic_fetch_sub( void * volatile * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1297 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1299 static void * atomic_fetch_sub( void ** pDest, ptrdiff_t val ) CDS_NOEXCEPT
1301 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1305 template <typename T>
1306 struct atomic_integral
1309 typename cds::details::aligned_type<T, sizeof(T)>::type volatile m_val;
1311 typedef atomic_integral_ops<T, sizeof(T)> atomic_ops;
1313 typedef T atomic_type;
1315 bool is_lock_free() const volatile CDS_NOEXCEPT
1319 bool is_lock_free() const CDS_NOEXCEPT
1323 void store(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1325 atomic_ops::atomic_store_explicit( &m_val, val, order );
1327 void store(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1329 atomic_ops::atomic_store_explicit( &m_val, val, order );
1332 T load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1334 return atomic_ops::atomic_load_explicit( &m_val, order );
1336 T load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1338 return atomic_ops::atomic_load_explicit( &m_val, order );
1341 operator T() const volatile CDS_NOEXCEPT
1345 operator T() const CDS_NOEXCEPT
1350 T exchange(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1352 return atomic_ops::atomic_exchange_explicit( &m_val, val, order );
1354 T exchange(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1356 return atomic_ops::atomic_exchange_explicit( &m_val, val, order );
1359 bool compare_exchange_weak(T& expected, T desired , memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1361 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_val, &expected, desired, success_order, failure_order );
1363 bool compare_exchange_weak(T& expected, T desired , memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1365 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_val, &expected, desired, success_order, failure_order );
1367 bool compare_exchange_strong(T& expected, T desired , memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1369 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_val, &expected, desired, success_order, failure_order );
1371 bool compare_exchange_strong(T& expected, T desired , memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1373 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_val, &expected, desired, success_order, failure_order );
1375 bool compare_exchange_weak(T& expected, T desired , memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1377 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1379 bool compare_exchange_weak(T& expected, T desired , memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1381 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1383 bool compare_exchange_strong(T& expected, T desired , memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1385 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1387 bool compare_exchange_strong(T& expected, T desired , memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1389 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1392 T fetch_add(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1394 return atomic_ops::atomic_fetch_add_explicit( &m_val, val, order );
1396 T fetch_add(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1398 return atomic_ops::atomic_fetch_add_explicit( &m_val, val, order );
1400 T fetch_sub(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1402 return atomic_ops::atomic_fetch_sub_explicit( &m_val, val, order );
1404 T fetch_sub(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1406 return atomic_ops::atomic_fetch_sub_explicit( &m_val, val, order );
1408 T fetch_and(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1410 return atomic_ops::atomic_fetch_and_explicit( &m_val, val, order );
1412 T fetch_and(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1414 return atomic_ops::atomic_fetch_and_explicit( &m_val, val, order );
1417 T fetch_or(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1419 return atomic_ops::atomic_fetch_or_explicit( &m_val, val, order );
1421 T fetch_or(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1423 return atomic_ops::atomic_fetch_or_explicit( &m_val, val, order );
1425 T fetch_xor(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1427 return atomic_ops::atomic_fetch_xor_explicit( &m_val, val, order );
1429 T fetch_xor(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1431 return atomic_ops::atomic_fetch_xor_explicit( &m_val, val, order );
1434 atomic_integral() = default;
1435 CDS_CONSTEXPR atomic_integral(T val) CDS_NOEXCEPT
1439 atomic_integral(const atomic_integral&) = delete;
1440 atomic_integral& operator=(const atomic_integral&) = delete;
1441 atomic_integral& operator=(const atomic_integral&) volatile = delete;
1443 T operator=(T val) volatile CDS_NOEXCEPT
1448 T operator=(T val) CDS_NOEXCEPT
1455 T operator++(int) volatile CDS_NOEXCEPT
1457 return fetch_add( 1 );
1459 T operator++(int) CDS_NOEXCEPT
1461 return fetch_add( 1 );
1463 T operator--(int) volatile CDS_NOEXCEPT
1465 return fetch_sub( 1 );
1467 T operator--(int) CDS_NOEXCEPT
1469 return fetch_sub( 1 );
1473 T operator++() volatile CDS_NOEXCEPT
1475 return fetch_add( 1 ) + 1;
1477 T operator++() CDS_NOEXCEPT
1479 return fetch_add( 1 ) + 1;
1481 T operator--() volatile CDS_NOEXCEPT
1483 return fetch_sub( 1 ) - 1;
1485 T operator--() CDS_NOEXCEPT
1487 return fetch_sub( 1 ) - 1;
1491 T operator+=(T val) volatile CDS_NOEXCEPT
1493 return fetch_add( val ) + val;
1495 T operator+=(T val) CDS_NOEXCEPT
1497 return fetch_add( val ) + val;
1499 T operator-=(T val) volatile CDS_NOEXCEPT
1501 return fetch_sub( val ) - val;
1503 T operator-=(T val) CDS_NOEXCEPT
1505 return fetch_sub( val ) - val;
1507 T operator&=(T val) volatile CDS_NOEXCEPT
1509 return fetch_and( val ) & val;
1511 T operator&=(T val) CDS_NOEXCEPT
1513 return fetch_and( val ) & val;
1515 T operator|=(T val) volatile CDS_NOEXCEPT
1517 return fetch_or( val ) | val;
1519 T operator|=(T val) CDS_NOEXCEPT
1521 return fetch_or( val ) | val;
1523 T operator^=(T val) volatile CDS_NOEXCEPT
1525 return fetch_xor( val ) ^ val;
1527 T operator^=(T val) CDS_NOEXCEPT
1529 return fetch_xor( val ) ^ val;
1533 template <typename Type>
1534 struct select_primary_type {
1535 typedef typename details::primary_type<sizeof(Type)>::type type;
1538 struct select_primary_type<bool> {
1542 } // namespace details
1548 typedef details::atomic_generic_ops<T, sizeof(T), typename details::select_primary_type<T>::type > atomic_ops;
1552 bool is_lock_free() const volatile CDS_NOEXCEPT
1556 bool is_lock_free() const CDS_NOEXCEPT
1561 void store(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1563 atomic_ops::atomic_store_explicit( &m_data, val, order );
1565 void store(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1567 atomic_ops::atomic_store_explicit( &m_data, val, order );
1570 T load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1572 return atomic_ops::atomic_load_explicit( &m_data, order );
1574 T load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1576 return atomic_ops::atomic_load_explicit( &m_data, order );
1579 operator T() const volatile CDS_NOEXCEPT
1583 operator T() const CDS_NOEXCEPT
1588 T exchange(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1590 return atomic_ops::atomic_exchange_explicit( &m_data, val, order );
1592 T exchange(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1594 return atomic_ops::atomic_exchange_explicit( &m_data, val, order );
1597 bool compare_exchange_weak(T& expected, T desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1599 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_data, &expected, desired, success_order, failure_order );
1601 bool compare_exchange_weak(T& expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1603 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_data, &expected, desired, success_order, failure_order );
1605 bool compare_exchange_strong(T& expected, T desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1607 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_data, &expected, desired, success_order, failure_order );
1609 bool compare_exchange_strong(T& expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1611 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_data, &expected, desired, success_order, failure_order );
1613 bool compare_exchange_weak(T& expected, T desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1615 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1617 bool compare_exchange_weak(T& expected, T desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1619 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1621 bool compare_exchange_strong(T& expected, T desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1623 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1625 bool compare_exchange_strong(T& expected, T desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1627 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1631 CDS_CONSTEXPR atomic(T val)
1635 atomic(const atomic&) = delete;
1636 atomic& operator=(const atomic&) = delete;
1637 atomic& operator=(const atomic&) volatile = delete;
1639 T operator=(T val) volatile CDS_NOEXCEPT
1644 T operator=(T val) CDS_NOEXCEPT
1651 # define CDS_DECLARE_ATOMIC_INTEGRAL( _type ) \
1653 struct atomic<_type>: public details::atomic_integral<_type> \
1656 typedef details::atomic_integral<_type> base_class ; \
1658 atomic() = default; \
1659 atomic(_type val) CDS_NOEXCEPT : base_class(val) {} \
1660 atomic(const atomic&) = delete; \
1661 atomic& operator=(const atomic&) = delete; \
1662 atomic& operator=(const atomic&) volatile = delete; \
1663 _type operator=(_type val) volatile CDS_NOEXCEPT { return base_class::operator=(val); } \
1664 _type operator=(_type val) CDS_NOEXCEPT { return base_class::operator=(val); } \
1667 CDS_DECLARE_ATOMIC_INTEGRAL(char)
1668 CDS_DECLARE_ATOMIC_INTEGRAL(signed char)
1669 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned char)
1670 CDS_DECLARE_ATOMIC_INTEGRAL(short)
1671 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned short)
1672 CDS_DECLARE_ATOMIC_INTEGRAL(int)
1673 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned int)
1674 CDS_DECLARE_ATOMIC_INTEGRAL(long)
1675 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned long)
1676 CDS_DECLARE_ATOMIC_INTEGRAL(long long)
1677 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned long long)
1678 //#if CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40400
1679 // CDS_DECLARE_ATOMIC_INTEGRAL(char16_t)
1680 // CDS_DECLARE_ATOMIC_INTEGRAL(char32_t)
1682 // CDS_DECLARE_ATOMIC_INTEGRAL(wchar_t)
1684 # undef CDS_DECLARE_ATOMIC_INTEGRAL
1687 template <typename T>
1692 typedef details::atomic_pointer<T> atomic_ops;
1694 bool is_lock_free() const volatile CDS_NOEXCEPT
1698 bool is_lock_free() const CDS_NOEXCEPT
1703 void store(T * val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1705 atomic_ops::atomic_store_explicit( &m_ptr, val, order );
1707 void store(T * val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1709 atomic_ops::atomic_store_explicit( &m_ptr, val, order );
1712 T * load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1714 return atomic_ops::atomic_load_explicit( &m_ptr, order );
1716 T * load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1718 return atomic_ops::atomic_load_explicit( &m_ptr, order );
1721 operator T *() const volatile CDS_NOEXCEPT
1725 operator T *() const CDS_NOEXCEPT
1730 T * exchange(T * val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1732 return atomic_ops::atomic_exchange_explicit( &m_ptr, val, order );
1734 T * exchange(T * val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1736 return atomic_ops::atomic_exchange_explicit( &m_ptr, val, order );
1739 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1741 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1743 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1745 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1747 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1749 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1751 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1753 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1755 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1757 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1759 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1761 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1763 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1765 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1767 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1769 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1772 T * fetch_add(ptrdiff_t offset, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1774 return atomic_ops::atomic_fetch_add_explicit( &m_ptr, offset, order );
1776 T * fetch_add(ptrdiff_t offset, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1778 return atomic_ops::atomic_fetch_add_explicit( &m_ptr, offset, order );
1781 T * fetch_sub(ptrdiff_t offset, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1783 return atomic_ops::atomic_fetch_sub_explicit( &m_ptr, offset, order );
1785 T * fetch_sub(ptrdiff_t offset, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1787 return atomic_ops::atomic_fetch_sub_explicit( &m_ptr, offset, order );
1791 CDS_CONSTEXPR atomic(T * val) CDS_NOEXCEPT
1795 atomic(const atomic&) = delete;
1796 atomic& operator=(const atomic&) = delete;
1797 atomic& operator=(const atomic&) volatile = delete;
1799 T * operator=(T * val) volatile CDS_NOEXCEPT
1804 T * operator=(T * val) CDS_NOEXCEPT
1812 typedef atomic<bool> atomic_bool;
1813 typedef atomic<char> atomic_char;
1814 typedef atomic<signed char> atomic_schar;
1815 typedef atomic<unsigned char> atomic_uchar;
1816 typedef atomic<short> atomic_short;
1817 typedef atomic<unsigned short> atomic_ushort;
1818 typedef atomic<int> atomic_int;
1819 typedef atomic<unsigned int> atomic_uint;
1820 typedef atomic<long> atomic_long;
1821 typedef atomic<unsigned long> atomic_ulong;
1822 typedef atomic<long long> atomic_llong;
1823 typedef atomic<unsigned long long> atomic_ullong;
1824 #if ( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40400 ) || CDS_COMPILER == CDS_COMPILER_CLANG
1825 typedef atomic<char16_t> atomic_char16_t;
1826 typedef atomic<char32_t> atomic_char32_t;
1828 typedef atomic<wchar_t> atomic_wchar_t;
1831 typedef atomic<std::int_least8_t> atomic_int_least8_t;
1832 typedef atomic<std::uint_least8_t> atomic_uint_least8_t;
1833 typedef atomic<std::int_least16_t> atomic_int_least16_t;
1834 typedef atomic<std::uint_least16_t> atomic_uint_least16_t;
1835 typedef atomic<std::int_least32_t> atomic_int_least32_t;
1836 typedef atomic<std::uint_least32_t> atomic_uint_least32_t;
1837 typedef atomic<std::int_least64_t> atomic_int_least64_t;
1838 typedef atomic<std::uint_least64_t> atomic_uint_least64_t;
1839 typedef atomic<std::int_fast8_t> atomic_int_fast8_t;
1840 typedef atomic<std::uint_fast8_t> atomic_uint_fast8_t;
1841 typedef atomic<std::int_fast16_t> atomic_int_fast16_t;
1842 typedef atomic<std::uint_fast16_t> atomic_uint_fast16_t;
1843 typedef atomic<std::int_fast32_t> atomic_int_fast32_t;
1844 typedef atomic<std::uint_fast32_t> atomic_uint_fast32_t;
1845 typedef atomic<std::int_fast64_t> atomic_int_fast64_t;
1846 typedef atomic<std::uint_fast64_t> atomic_uint_fast64_t;
1847 typedef atomic<intptr_t> atomic_intptr_t;
1848 typedef atomic<uintptr_t> atomic_uintptr_t;
1849 typedef atomic<size_t> atomic_size_t;
1850 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1851 typedef atomic<std::intmax_t> atomic_intmax_t;
1852 typedef atomic<std::uintmax_t> atomic_uintmax_t;
1855 static inline bool atomic_is_lock_free(const volatile atomic<T> * p) CDS_NOEXCEPT
1857 return p->is_lock_free();
1861 static inline bool atomic_is_lock_free(const atomic<T> * p ) CDS_NOEXCEPT
1863 return p->is_lock_free();
1868 static inline void atomic_init(volatile atomic<T> * p, T val) CDS_NOEXCEPT
1874 static inline void atomic_init( atomic<T> * p, T val) CDS_NOEXCEPT
1881 static inline void atomic_store(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1886 static inline void atomic_store(atomic<T>* p, T val) CDS_NOEXCEPT
1892 static inline void atomic_store_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1894 p->store( val, order );
1897 static inline void atomic_store_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1899 p->store( val, order );
1903 static inline T atomic_load(const volatile atomic<T>* p) CDS_NOEXCEPT
1908 static inline T atomic_load(const atomic<T>* p) CDS_NOEXCEPT
1914 static inline T atomic_load_explicit(const volatile atomic<T>* p, memory_order order) CDS_NOEXCEPT
1916 return p->load( order );
1919 static inline T atomic_load_explicit(const atomic<T>* p, memory_order order) CDS_NOEXCEPT
1921 return p->load( order );
1925 static inline T atomic_exchange(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1927 return p->exchange( val );
1930 static inline T atomic_exchange(atomic<T>* p, T val ) CDS_NOEXCEPT
1932 return p->exchange( val );
1936 static inline T atomic_exchange_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1938 return p->exchange( val, order );
1941 static inline T atomic_exchange_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1943 return p->exchange( val, order );
1947 static inline bool atomic_compare_exchange_weak(volatile atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1949 return p->compare_exchange_weak( *expected, desired );
1952 static inline bool atomic_compare_exchange_weak(atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1954 return p->compare_exchange_weak( *expected, desired );
1958 static inline bool atomic_compare_exchange_strong(volatile atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1960 return p->compare_exchange_strong( *expected, desired );
1963 static inline bool atomic_compare_exchange_strong(atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1965 return p->compare_exchange_strong( *expected, desired );
1969 static inline bool atomic_compare_exchange_weak_explicit(volatile atomic<T>* p, T* expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1971 return p->compare_exchange_weak( *expected, desired, success_order, failure_order );
1974 static inline bool atomic_compare_exchange_weak_explicit(atomic<T>* p, T* expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1976 return p->compare_exchange_weak( *expected, desired, success_order, failure_order );
1980 static inline bool atomic_compare_exchange_strong_explicit(volatile atomic<T>* p, T* expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1982 return p->compare_exchange_strong( *expected, desired, success_order, failure_order );
1985 static inline bool atomic_compare_exchange_strong_explicit(atomic<T>* p, T* expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1987 return p->compare_exchange_strong( *expected, desired, success_order, failure_order );
1991 static inline T atomic_fetch_add(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1993 return p->fetch_add( val );
1996 static inline T atomic_fetch_add(atomic<T>* p, T val) CDS_NOEXCEPT
1998 return p->fetch_add( val );
2001 static inline T * atomic_fetch_add(volatile atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2003 return p->fetch_add( offset );
2006 static inline T * atomic_fetch_add(atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2008 return p->fetch_add( offset );
2012 static inline T atomic_fetch_add_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2014 return p->fetch_add( val, order );
2017 static inline T atomic_fetch_add_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2019 return p->fetch_add( val, order );
2022 static inline T * atomic_fetch_add_explicit(volatile atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2024 return p->fetch_add( offset, order );
2027 static inline T * atomic_fetch_add_explicit(atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2029 return p->fetch_add( offset, order );
2033 static inline T atomic_fetch_sub(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2035 return p->fetch_sub( val );
2038 static inline T atomic_fetch_sub(atomic<T>* p, T val) CDS_NOEXCEPT
2040 return p->fetch_sub( val );
2043 static inline T * atomic_fetch_sub(volatile atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2045 return p->fetch_sub( offset );
2048 static inline T * atomic_fetch_sub(atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2050 return p->fetch_sub( offset );
2054 static inline T atomic_fetch_sub_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2056 return p->fetch_sub( val, order );
2059 static inline T atomic_fetch_sub_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2061 return p->fetch_sub( val, order );
2064 static inline T * atomic_fetch_sub_explicit(volatile atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2066 return p->fetch_sub( offset, order );
2069 static inline T * atomic_fetch_sub_explicit(atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2071 return p->fetch_sub( offset, order );
2075 static inline T atomic_fetch_and(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2077 return p->fetch_and( val );
2080 static inline T atomic_fetch_and(atomic<T>* p, T val) CDS_NOEXCEPT
2082 return p->fetch_and( val );
2086 static inline T atomic_fetch_and_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2088 return p->fetch_and( val, order );
2091 static inline T atomic_fetch_and_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2093 return p->fetch_and( val, order );
2097 static inline T atomic_fetch_or(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2099 return p->fetch_or( val );
2102 static inline T atomic_fetch_or(atomic<T>* p, T val) CDS_NOEXCEPT
2104 return p->fetch_or( val );
2108 static inline T atomic_fetch_or_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2110 return p->fetch_or( val, order );
2113 static inline T atomic_fetch_or_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2115 return p->fetch_or( val, order );
2119 static inline T atomic_fetch_xor(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2121 return p->fetch_xor( val );
2124 static inline T atomic_fetch_xor(atomic<T>* p, T val) CDS_NOEXCEPT
2126 return p->fetch_xor( val );
2130 static inline T atomic_fetch_xor_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2132 return p->fetch_xor( val, order );
2135 static inline T atomic_fetch_xor_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2137 return p->fetch_xor( val, order );
2141 typedef struct atomic_flag
2143 void clear( memory_order order = memory_order_seq_cst ) volatile CDS_NOEXCEPT
2145 assert( order != memory_order_acquire
2146 && order != memory_order_acq_rel
2147 && order != memory_order_consume
2149 platform::atomic_flag_clear( &m_Flag, order );
2151 void clear( memory_order order = memory_order_seq_cst ) CDS_NOEXCEPT
2153 assert( order != memory_order_acquire
2154 && order != memory_order_acq_rel
2155 && order != memory_order_consume
2157 platform::atomic_flag_clear( &m_Flag, order );
2160 bool test_and_set( memory_order order = memory_order_seq_cst ) volatile CDS_NOEXCEPT
2162 return platform::atomic_flag_tas( &m_Flag, order );
2164 bool test_and_set( memory_order order = memory_order_seq_cst ) CDS_NOEXCEPT
2166 return platform::atomic_flag_tas( &m_Flag, order );
2169 atomic_flag() = default;
2171 atomic_flag(const atomic_flag&) = delete;
2172 atomic_flag& operator=(const atomic_flag&) = delete;
2173 atomic_flag& operator=(const atomic_flag&) volatile = delete;
2175 platform::atomic_flag_type volatile m_Flag;
2178 static inline bool atomic_flag_test_and_set(volatile atomic_flag* p) CDS_NOEXCEPT
2180 return p->test_and_set();
2182 static inline bool atomic_flag_test_and_set(atomic_flag * p) CDS_NOEXCEPT
2184 return p->test_and_set();
2186 static inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag* p, memory_order order) CDS_NOEXCEPT
2188 return p->test_and_set( order );
2190 static inline bool atomic_flag_test_and_set_explicit(atomic_flag* p, memory_order order) CDS_NOEXCEPT
2192 return p->test_and_set( order );
2194 static inline void atomic_flag_clear(volatile atomic_flag* p) CDS_NOEXCEPT
2198 static inline void atomic_flag_clear(atomic_flag* p) CDS_NOEXCEPT
2202 static inline void atomic_flag_clear_explicit(volatile atomic_flag* p, memory_order order) CDS_NOEXCEPT
2204 return p->clear( order );
2206 static inline void atomic_flag_clear_explicit(atomic_flag* p, memory_order order) CDS_NOEXCEPT
2208 return p->clear( order );
2212 static inline void atomic_thread_fence(memory_order order) CDS_NOEXCEPT
2214 platform::thread_fence( order );
2215 CDS_COMPILER_RW_BARRIER;
2217 static inline void atomic_signal_fence(memory_order order) CDS_NOEXCEPT
2219 platform::signal_fence( order );
2222 }} // namespace cds::cxx11_atomic
2225 #endif // #ifndef CDSLIB_COMPILER_CXX11_ATOMIC_H