3 #ifndef __CDS_COMPILER_CXX11_ATOMIC_H
4 #define __CDS_COMPILER_CXX11_ATOMIC_H
7 #include <cds/details/defs.h>
8 #include <cds/details/aligned_type.h>
10 namespace cds { namespace cxx11_atomic {
11 typedef enum memory_order {
20 }} // namespace cds::cxx11_atomic
23 #if CDS_COMPILER == CDS_COMPILER_MSVC || (CDS_COMPILER == CDS_COMPILER_INTEL && CDS_OS_INTERFACE == CDS_OSI_WINDOWS)
24 # if CDS_PROCESSOR_ARCH == CDS_PROCESSOR_X86
25 # include <cds/compiler/vc/x86/cxx11_atomic.h>
26 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_AMD64
27 # include <cds/compiler/vc/amd64/cxx11_atomic.h>
29 # error "MS VC++ compiler: unsupported processor architecture"
31 #elif CDS_COMPILER == CDS_COMPILER_GCC || CDS_COMPILER == CDS_COMPILER_CLANG || CDS_COMPILER == CDS_COMPILER_INTEL
32 # if CDS_PROCESSOR_ARCH == CDS_PROCESSOR_X86
33 # include <cds/compiler/gcc/x86/cxx11_atomic.h>
34 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_AMD64
35 # include <cds/compiler/gcc/amd64/cxx11_atomic.h>
36 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_IA64
37 # include <cds/compiler/gcc/ia64/cxx11_atomic.h>
38 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_SPARC
39 # include <cds/compiler/gcc/sparc/cxx11_atomic.h>
40 # elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_PPC64
41 # include <cds/compiler/gcc/ppc64/cxx11_atomic.h>
42 //# elif CDS_PROCESSOR_ARCH == CDS_PROCESSOR_ARM7
43 //# include <cds/compiler/gcc/arm7/cxx11_atomic.h>
45 # error "GCC compiler: unsupported processor architecture. Try to use native C++11 atomic or boost.atomic"
48 # error "Undefined compiler"
51 // In C++11, make_unsigned is declared in <type_traits>
52 #include <boost/type_traits/make_unsigned.hpp> // for make_unsigned
54 namespace cds { namespace cxx11_atomic {
56 // forward declarations
62 template <typename T, size_t Size, typename Primary = T >
63 struct atomic_generic_ops;
65 template <typename T, size_t Size>
66 struct atomic_integral_ops;
68 template <size_t TypeSize>
72 struct primary_type<1>
74 typedef cds::uint8_t type;
77 struct primary_type<2>
79 typedef cds::uint16_t type;
82 struct primary_type<4>
84 typedef cds::uint32_t type;
87 struct primary_type<8>
89 typedef cds::uint64_t type;
92 template <typename T, typename Primary>
93 struct make_atomic_primary
95 typedef T source_type;
96 typedef Primary primary_type;
98 static primary_type volatile * ptr( source_type volatile * p ) CDS_NOEXCEPT
100 return reinterpret_cast<primary_type volatile *>(p);
102 static primary_type const volatile * ptr( source_type const volatile * p ) CDS_NOEXCEPT
104 return reinterpret_cast<primary_type const volatile *>(p);
107 static primary_type val( source_type v ) CDS_NOEXCEPT
109 return *reinterpret_cast<primary_type*>(&v);
112 static primary_type& ref( source_type& v ) CDS_NOEXCEPT
114 return reinterpret_cast<primary_type&>(v);
117 static primary_type const& ref( source_type const& v ) CDS_NOEXCEPT
119 return reinterpret_cast<primary_type const&>(v);
122 static source_type ret( primary_type r ) CDS_NOEXCEPT
124 return *reinterpret_cast<source_type *>(&r);
128 template <typename T>
129 struct make_atomic_primary<T, T>
131 typedef T source_type;
132 typedef T primary_type;
134 static primary_type volatile * ptr( source_type volatile * p ) CDS_NOEXCEPT
138 static primary_type const volatile * ptr( source_type const volatile * p ) CDS_NOEXCEPT
143 static primary_type val( source_type v ) CDS_NOEXCEPT
148 static primary_type& ref( source_type& v ) CDS_NOEXCEPT
153 static source_type ret( primary_type r ) CDS_NOEXCEPT
159 template <typename T>
160 struct atomic_integral_bitwise_ops
163 typedef typename boost::make_unsigned<T>::type unsigned_type;
164 typedef atomic_generic_ops<unsigned_type, sizeof(unsigned_type)> atomic_ops;
166 static T fetch_and(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
168 unsigned_type cur = atomic_ops::atomic_load_explicit( reinterpret_cast<unsigned_type volatile *>(pDest), memory_order_relaxed );
169 do {} while ( !atomic_ops::atomic_compare_exchange_weak_explicit(
170 reinterpret_cast<unsigned_type volatile *>(pDest), &cur, cur & unsigned_type(val), order, memory_order_relaxed ));
174 static T fetch_or(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
176 unsigned_type cur = atomic_ops::atomic_load_explicit( reinterpret_cast<unsigned_type volatile *>(pDest), memory_order_relaxed );
177 do {} while ( !atomic_ops::atomic_compare_exchange_weak_explicit(
178 reinterpret_cast<unsigned_type volatile *>(pDest), &cur, cur | unsigned_type(val), order, memory_order_relaxed ));
182 static T fetch_xor(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
184 unsigned_type cur = atomic_ops::atomic_load_explicit( reinterpret_cast<unsigned_type volatile *>(pDest), memory_order_relaxed );
185 do {} while ( !atomic_ops::atomic_compare_exchange_weak_explicit(
186 reinterpret_cast<unsigned_type volatile *>(pDest), &cur, cur ^ unsigned_type(val), order, memory_order_relaxed ));
192 // 8-bit atomic operations
194 template <typename T, typename Primary>
195 struct atomic_generic_ops< T, 1, Primary >
197 typedef make_atomic_primary<T, Primary> primary;
200 static void atomic_store_explicit( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
202 platform::store8( primary::ptr(pDest), primary::val(v), order );
204 static void atomic_store_explicit( T * pDest, T v, memory_order order ) CDS_NOEXCEPT
206 platform::store8( primary::ptr(pDest), primary::val(v), order );
208 static void atomic_store( T volatile * pDest, T v ) CDS_NOEXCEPT
210 atomic_store_explicit( pDest, v, memory_order_seq_cst );
212 static void atomic_store( T * pDest, T v ) CDS_NOEXCEPT
214 atomic_store_explicit( pDest, v, memory_order_seq_cst );
218 static T atomic_load_explicit( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
220 return primary::ret( platform::load8( primary::ptr(pSrc), order ));
222 static T atomic_load_explicit( T const * pSrc, memory_order order ) CDS_NOEXCEPT
224 return primary::ret( platform::load8( primary::ptr(pSrc), order ));
226 static T atomic_load( T volatile const * pSrc ) CDS_NOEXCEPT
228 return atomic_load_explicit( pSrc, memory_order_seq_cst );
230 static T atomic_load( T const * pSrc ) CDS_NOEXCEPT
232 return atomic_load_explicit( pSrc, memory_order_seq_cst );
236 static T atomic_exchange_explicit( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
238 return primary::ret( platform::exchange8( primary::ptr(pDest), primary::val(val), order ));
240 static T atomic_exchange_explicit( T * pDest, T val, memory_order order ) CDS_NOEXCEPT
242 return primary::ret( platform::exchange8( primary::ptr(pDest), primary::val(val), order ));
244 static T atomic_exchange( T volatile * pDest, T val ) CDS_NOEXCEPT
246 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
248 static T atomic_exchange( T * pDest, T val ) CDS_NOEXCEPT
250 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
254 static bool atomic_compare_exchange_weak_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
257 return platform::cas8_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
259 static bool atomic_compare_exchange_weak_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
262 return platform::cas8_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
264 static bool atomic_compare_exchange_weak( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
266 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
268 static bool atomic_compare_exchange_weak( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
270 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
272 static bool atomic_compare_exchange_strong_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
275 return platform::cas8_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
277 static bool atomic_compare_exchange_strong_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
280 return platform::cas8_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
282 static bool atomic_compare_exchange_strong( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
284 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
286 static bool atomic_compare_exchange_strong( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
288 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
292 template <typename T>
293 struct atomic_integral_ops< T, 1 >
294 : atomic_generic_ops<T, 1, T >
295 , atomic_integral_bitwise_ops<T>
297 typedef atomic_integral_bitwise_ops<T> bitwise_ops;
300 static T atomic_fetch_add_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
302 # ifdef CDS_ATOMIC_fetch8_add_defined
303 return platform::fetch8_add( pDest, val, order );
305 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
306 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
310 static T atomic_fetch_add_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
312 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
314 static T atomic_fetch_add( T volatile * pDest, T val ) CDS_NOEXCEPT
316 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
318 static T atomic_fetch_add( T * pDest, T val ) CDS_NOEXCEPT
320 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
324 static T atomic_fetch_sub_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
326 # ifdef CDS_ATOMIC_fetch8_sub_defined
327 return platform::fetch8_sub( pDest, val, order );
329 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
330 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
334 static T atomic_fetch_sub_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
336 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
338 static T atomic_fetch_sub( T volatile * pDest, T val ) CDS_NOEXCEPT
340 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
342 static T atomic_fetch_sub( T * pDest, T val ) CDS_NOEXCEPT
344 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
348 static T atomic_fetch_and_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
350 # ifdef CDS_ATOMIC_fetch8_and_defined
351 return platform::fetch8_and( pDest, val, order );
353 return bitwise_ops::fetch_and( pDest, val, order );
356 static T atomic_fetch_and_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
358 return atomic_fetch_and_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
360 static T atomic_fetch_and( T volatile * pDest, T val ) CDS_NOEXCEPT
362 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
364 static T atomic_fetch_and( T * pDest, T val ) CDS_NOEXCEPT
366 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
370 static T atomic_fetch_or_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
372 # ifdef CDS_ATOMIC_fetch8_or_defined
373 return platform::fetch8_or( pDest, val, order );
375 return bitwise_ops::fetch_or( pDest, val, order );
378 static T atomic_fetch_or_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
380 return atomic_fetch_or_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
382 static T atomic_fetch_or( T volatile * pDest, T val ) CDS_NOEXCEPT
384 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
386 static T atomic_fetch_or( T * pDest, T val ) CDS_NOEXCEPT
388 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
392 static T atomic_fetch_xor_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
394 # ifdef CDS_ATOMIC_fetch8_xor_defined
395 return platform::fetch8_xor( pDest, val, order );
397 return bitwise_ops::fetch_xor( pDest, val, order );
400 static T atomic_fetch_xor_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
402 return atomic_fetch_xor_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
404 static T atomic_fetch_xor( T volatile * pDest, T val ) CDS_NOEXCEPT
406 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
408 static T atomic_fetch_xor( T * pDest, T val ) CDS_NOEXCEPT
410 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
414 // 16-bit atomic operations
416 template <typename T, typename Primary>
417 struct atomic_generic_ops< T, 2, Primary >
419 typedef make_atomic_primary<T, Primary> primary;
422 static void atomic_store_explicit( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
424 platform::store16( primary::ptr(pDest), primary::val(v), order );
426 static void atomic_store_explicit( T * pDest, T v, memory_order order ) CDS_NOEXCEPT
428 platform::store16( primary::ptr(pDest), primary::val(v), order );
430 static void atomic_store( T volatile * pDest, T v ) CDS_NOEXCEPT
432 atomic_store_explicit( pDest, v, memory_order_seq_cst );
434 static void atomic_store( T * pDest, T v ) CDS_NOEXCEPT
436 atomic_store_explicit( pDest, v, memory_order_seq_cst );
440 static T atomic_load_explicit( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
442 return primary::ret( platform::load16( primary::ptr(pSrc), order ));
444 static T atomic_load_explicit( T const * pSrc, memory_order order ) CDS_NOEXCEPT
446 return primary::ret( platform::load16( primary::ptr(pSrc), order ));
448 static T atomic_load( T volatile const * pSrc ) CDS_NOEXCEPT
450 return atomic_load_explicit( pSrc, memory_order_seq_cst );
452 static T atomic_load( T const * pSrc ) CDS_NOEXCEPT
454 return atomic_load_explicit( pSrc, memory_order_seq_cst );
458 static T atomic_exchange_explicit( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
460 return primary::ret( platform::exchange16( primary::ptr(pDest), primary::val(val), order ));
462 static T atomic_exchange_explicit( T * pDest, T val, memory_order order ) CDS_NOEXCEPT
464 return primary::ret( platform::exchange16( primary::ptr(pDest), primary::val(val), order ));
466 static T atomic_exchange( T volatile * pDest, T val ) CDS_NOEXCEPT
468 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
470 static T atomic_exchange( T * pDest, T val ) CDS_NOEXCEPT
472 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
476 static bool atomic_compare_exchange_weak_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
479 return platform::cas16_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
481 static bool atomic_compare_exchange_weak_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
484 return platform::cas16_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
486 static bool atomic_compare_exchange_weak( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
488 return atomic_compare_exchange_weak_explicit( pDest, expected, primary::val(desired), memory_order_seq_cst, memory_order_relaxed );
490 static bool atomic_compare_exchange_weak( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
492 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
494 static bool atomic_compare_exchange_strong_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
497 return platform::cas16_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
499 static bool atomic_compare_exchange_strong_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
502 return platform::cas16_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
504 static bool atomic_compare_exchange_strong( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
506 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
508 static bool atomic_compare_exchange_strong( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
510 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
514 template <typename T>
515 struct atomic_integral_ops< T, 2 >
516 : atomic_generic_ops< T, 2, T >
517 , atomic_integral_bitwise_ops<T>
519 typedef atomic_integral_bitwise_ops<T> bitwise_ops;
522 static T atomic_fetch_add_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
524 # ifdef CDS_ATOMIC_fetch16_add_defined
525 return platform::fetch16_add( pDest, val, order );
527 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
528 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
532 static T atomic_fetch_add_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
534 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
536 static T atomic_fetch_add( T volatile * pDest, T val ) CDS_NOEXCEPT
538 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
540 static T atomic_fetch_add( T * pDest, T val ) CDS_NOEXCEPT
542 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
546 static T atomic_fetch_sub_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
548 # ifdef CDS_ATOMIC_fetch16_sub_defined
549 return platform::fetch16_sub( pDest, val, order );
551 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
552 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
556 static T atomic_fetch_sub_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
558 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
560 static T atomic_fetch_sub( T volatile * pDest, T val ) CDS_NOEXCEPT
562 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
564 static T atomic_fetch_sub( T * pDest, T val ) CDS_NOEXCEPT
566 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
570 static T atomic_fetch_and_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
572 # ifdef CDS_ATOMIC_fetch16_and_defined
573 return platform::fetch16_and( pDest, val, order );
575 return bitwise_ops::fetch_and( pDest, val, order );
578 static T atomic_fetch_and_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
580 return atomic_fetch_and_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
582 static T atomic_fetch_and( T volatile * pDest, T val ) CDS_NOEXCEPT
584 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
586 static T atomic_fetch_and( T * pDest, T val ) CDS_NOEXCEPT
588 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
592 static T atomic_fetch_or_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
594 # ifdef CDS_ATOMIC_fetch16_or_defined
595 return platform::fetch16_or( pDest, val, order );
597 return bitwise_ops::fetch_or( pDest, val, order );
600 static T atomic_fetch_or_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
602 return atomic_fetch_or_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
604 static T atomic_fetch_or( T volatile * pDest, T val ) CDS_NOEXCEPT
606 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
608 static T atomic_fetch_or( T * pDest, T val ) CDS_NOEXCEPT
610 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
614 static T atomic_fetch_xor_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
616 # ifdef CDS_ATOMIC_fetch16_xor_defined
617 return platform::fetch16_xor( pDest, val, order );
619 return bitwise_ops::fetch_xor( pDest, val, order );
622 static T atomic_fetch_xor_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
624 return atomic_fetch_xor_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
626 static T atomic_fetch_xor( T volatile * pDest, T val ) CDS_NOEXCEPT
628 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
630 static T atomic_fetch_xor( T * pDest, T val ) CDS_NOEXCEPT
632 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
636 // 32-bit atomic operations
638 template <typename T, typename Primary>
639 struct atomic_generic_ops< T, 4, Primary >
641 typedef make_atomic_primary<T, Primary> primary;
644 static void atomic_store_explicit( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
646 platform::store32( primary::ptr(pDest), primary::val(v), order );
648 static void atomic_store_explicit( T * pDest, T v, memory_order order ) CDS_NOEXCEPT
650 platform::store32( primary::ptr(pDest), primary::val(v), order );
652 static void atomic_store( T volatile * pDest, T v ) CDS_NOEXCEPT
654 atomic_store_explicit( pDest, v, memory_order_seq_cst );
656 static void atomic_store( T * pDest, T v ) CDS_NOEXCEPT
658 atomic_store_explicit( pDest, v, memory_order_seq_cst );
662 static T atomic_load_explicit( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
664 return primary::ret( platform::load32( primary::ptr(pSrc), order ));
666 static T atomic_load_explicit( T const * pSrc, memory_order order ) CDS_NOEXCEPT
668 return primary::ret( platform::load32( primary::ptr(pSrc), order ));
670 static T atomic_load( T volatile const * pSrc ) CDS_NOEXCEPT
672 return atomic_load_explicit( pSrc, memory_order_seq_cst );
674 static T atomic_load( T const * pSrc ) CDS_NOEXCEPT
676 return atomic_load_explicit( pSrc, memory_order_seq_cst );
680 static T atomic_exchange_explicit( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
682 return primary::ret( platform::exchange32( primary::ptr(pDest), primary::val(val), order ));
684 static T atomic_exchange_explicit( T * pDest, T val, memory_order order ) CDS_NOEXCEPT
686 return primary::ret( platform::exchange32( primary::ptr(pDest), primary::val(val), order ));
688 static T atomic_exchange( T volatile * pDest, T val ) CDS_NOEXCEPT
690 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
692 static T atomic_exchange( T * pDest, T val ) CDS_NOEXCEPT
694 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
698 static bool atomic_compare_exchange_weak_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
701 return platform::cas32_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
703 static bool atomic_compare_exchange_weak_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
706 return platform::cas32_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
708 static bool atomic_compare_exchange_weak( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
710 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
712 static bool atomic_compare_exchange_weak( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
714 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
716 static bool atomic_compare_exchange_strong_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
719 return platform::cas32_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
721 static bool atomic_compare_exchange_strong_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
724 return platform::cas32_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
726 static bool atomic_compare_exchange_strong( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
728 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
730 static bool atomic_compare_exchange_strong( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
732 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
736 template <typename T>
737 struct atomic_integral_ops< T, 4 >
738 : atomic_generic_ops< T, 4, T >
739 , atomic_integral_bitwise_ops<T>
741 typedef atomic_integral_bitwise_ops<T> bitwise_ops;
743 static T atomic_fetch_add_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
745 # ifdef CDS_ATOMIC_fetch32_add_defined
746 return platform::fetch32_add( pDest, val, order );
748 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
749 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
753 static T atomic_fetch_add_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
755 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
757 static T atomic_fetch_add( T volatile * pDest, T val ) CDS_NOEXCEPT
759 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
761 static T atomic_fetch_add( T * pDest, T val ) CDS_NOEXCEPT
763 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
767 static T atomic_fetch_sub_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
769 # ifdef CDS_ATOMIC_fetch32_sub_defined
770 return platform::fetch32_sub( pDest, val, order );
772 T cur = atomic_load_explicit( pDest, memory_order_relaxed );
773 do {} while ( !atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
777 static T atomic_fetch_sub_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
779 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
781 static T atomic_fetch_sub( T volatile * pDest, T val ) CDS_NOEXCEPT
783 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
785 static T atomic_fetch_sub( T * pDest, T val ) CDS_NOEXCEPT
787 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
791 static T atomic_fetch_and_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
793 # ifdef CDS_ATOMIC_fetch32_and_defined
794 return platform::fetch32_and( pDest, val, order );
796 return bitwise_ops::fetch_and( pDest, val, order );
799 static T atomic_fetch_and_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
801 return atomic_fetch_and_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
803 static T atomic_fetch_and( T volatile * pDest, T val ) CDS_NOEXCEPT
805 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
807 static T atomic_fetch_and( T * pDest, T val ) CDS_NOEXCEPT
809 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
813 static T atomic_fetch_or_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
815 # ifdef CDS_ATOMIC_fetch32_or_defined
816 return platform::fetch32_or( pDest, val, order );
818 return bitwise_ops::fetch_or( pDest, val, order );
821 static T atomic_fetch_or_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
823 return atomic_fetch_or_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
825 static T atomic_fetch_or( T volatile * pDest, T val ) CDS_NOEXCEPT
827 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
829 static T atomic_fetch_or( T * pDest, T val ) CDS_NOEXCEPT
831 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
835 static T atomic_fetch_xor_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
837 # ifdef CDS_ATOMIC_fetch32_xor_defined
838 return platform::fetch32_xor( pDest, val, order );
840 return bitwise_ops::fetch_xor( pDest, val, order );
843 static T atomic_fetch_xor_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
845 return atomic_fetch_xor_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
847 static T atomic_fetch_xor( T volatile * pDest, T val ) CDS_NOEXCEPT
849 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
851 static T atomic_fetch_xor( T * pDest, T val ) CDS_NOEXCEPT
853 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
858 // 64-bit atomic operations
860 template <typename T, typename Primary>
861 struct atomic_generic_ops< T, 8, Primary >
863 typedef make_atomic_primary<T, Primary> primary;
866 static void atomic_store_explicit( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
868 platform::store64( primary::ptr(pDest), primary::val(v), order );
870 static void atomic_store_explicit( T * pDest, T v, memory_order order ) CDS_NOEXCEPT
872 platform::store64( primary::ptr(pDest), primary::val(v), order );
874 static void atomic_store( T volatile * pDest, T v ) CDS_NOEXCEPT
876 atomic_store_explicit( pDest, v, memory_order_seq_cst );
878 static void atomic_store( T * pDest, T v ) CDS_NOEXCEPT
880 atomic_store_explicit( pDest, v, memory_order_seq_cst );
884 static T atomic_load_explicit( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
886 return primary::ret( platform::load64( primary::ptr(pSrc), order ));
888 static T atomic_load_explicit( T const * pSrc, memory_order order ) CDS_NOEXCEPT
890 return primary::ret( platform::load64( primary::ptr(pSrc), order ));
892 static T atomic_load( T volatile const * pSrc ) CDS_NOEXCEPT
894 return atomic_load_explicit( pSrc, memory_order_seq_cst );
896 static T atomic_load( T const * pSrc ) CDS_NOEXCEPT
898 return atomic_load_explicit( pSrc, memory_order_seq_cst );
902 static T atomic_exchange_explicit( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
904 return primary::ret( platform::exchange64( primary::ptr(pDest), primary::val(val), order ));
906 static T atomic_exchange_explicit( T * pDest, T val, memory_order order ) CDS_NOEXCEPT
908 return primary::ret( platform::exchange64( primary::ptr(pDest), primary::val(val), order ));
910 static T atomic_exchange( T volatile * pDest, T val ) CDS_NOEXCEPT
912 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
914 static T atomic_exchange( T * pDest, T val ) CDS_NOEXCEPT
916 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
920 static bool atomic_compare_exchange_weak_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
923 return platform::cas64_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
925 static bool atomic_compare_exchange_weak_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
928 return platform::cas64_weak( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
930 static bool atomic_compare_exchange_weak( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
932 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
934 static bool atomic_compare_exchange_weak( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
936 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
938 static bool atomic_compare_exchange_strong_explicit( T volatile * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
941 return platform::cas64_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
943 static bool atomic_compare_exchange_strong_explicit( T * pDest, T * expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
946 return platform::cas64_strong( primary::ptr(pDest), primary::ref(*expected), primary::val(desired), mo_success, mo_fail );
948 static bool atomic_compare_exchange_strong( T volatile * pDest, T * expected, T desired ) CDS_NOEXCEPT
950 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
952 static bool atomic_compare_exchange_strong( T * pDest, T * expected, T desired ) CDS_NOEXCEPT
954 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
959 template <typename T>
960 struct atomic_integral_ops< T, 8 >
961 : atomic_generic_ops< T, 8, T >
962 , atomic_integral_bitwise_ops<T>
964 typedef atomic_integral_bitwise_ops<T> bitwise_ops;
965 typedef atomic_generic_ops<T, 8, T> general_ops;
968 static T atomic_fetch_add_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
970 # ifdef CDS_ATOMIC_fetch64_add_defined
971 return platform::fetch64_add( pDest, val, order );
973 T cur = general_ops::atomic_load_explicit( pDest, memory_order_relaxed );
974 do {} while ( !general_ops::atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
978 static T atomic_fetch_add_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
980 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
982 static T atomic_fetch_add( T volatile * pDest, T val ) CDS_NOEXCEPT
984 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
986 static T atomic_fetch_add( T * pDest, T val ) CDS_NOEXCEPT
988 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
992 static T atomic_fetch_sub_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
994 # ifdef CDS_ATOMIC_fetch64_sub_defined
995 return platform::fetch64_sub( pDest, val, order );
997 T cur = general_ops::atomic_load_explicit( pDest, memory_order_relaxed );
998 do {} while ( !general_ops::atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
1002 static T atomic_fetch_sub_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1004 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1006 static T atomic_fetch_sub( T volatile * pDest, T val ) CDS_NOEXCEPT
1008 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1010 static T atomic_fetch_sub( T * pDest, T val ) CDS_NOEXCEPT
1012 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1016 static T atomic_fetch_and_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
1018 # ifdef CDS_ATOMIC_fetch64_and_defined
1019 return platform::fetch64_and( pDest, val, order );
1021 return bitwise_ops::fetch_and( pDest, val, order );
1024 static T atomic_fetch_and_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1026 return atomic_fetch_and_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1028 static T atomic_fetch_and( T volatile * pDest, T val ) CDS_NOEXCEPT
1030 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
1032 static T atomic_fetch_and( T * pDest, T val ) CDS_NOEXCEPT
1034 return atomic_fetch_and_explicit( pDest, val, memory_order_seq_cst );
1038 static T atomic_fetch_or_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
1040 # ifdef CDS_ATOMIC_fetch64_or_defined
1041 return platform::fetch64_or( pDest, val, order );
1043 return bitwise_ops::fetch_or( pDest, val, order );
1046 static T atomic_fetch_or_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1048 return atomic_fetch_or_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1050 static T atomic_fetch_or( T volatile * pDest, T val ) CDS_NOEXCEPT
1052 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
1054 static T atomic_fetch_or( T * pDest, T val ) CDS_NOEXCEPT
1056 return atomic_fetch_or_explicit( pDest, val, memory_order_seq_cst );
1060 static T atomic_fetch_xor_explicit(T volatile * pDest, T val, memory_order order) CDS_NOEXCEPT
1062 # ifdef CDS_ATOMIC_fetch64_xor_defined
1063 return platform::fetch64_xor( pDest, val, order );
1065 return bitwise_ops::fetch_xor( pDest, val, order );
1068 static T atomic_fetch_xor_explicit(T * pDest, T val , memory_order order) CDS_NOEXCEPT
1070 return atomic_fetch_xor_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1072 static T atomic_fetch_xor( T volatile * pDest, T val ) CDS_NOEXCEPT
1074 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
1076 static T atomic_fetch_xor( T * pDest, T val ) CDS_NOEXCEPT
1078 return atomic_fetch_xor_explicit( pDest, val, memory_order_seq_cst );
1083 // atomic pointer operations
1084 template <typename T>
1085 struct atomic_pointer_base
1088 static void atomic_store_explicit( T * volatile * pDest, T * v, memory_order order ) CDS_NOEXCEPT
1090 platform::store_ptr( pDest, v, order );
1092 static void atomic_store_explicit( T * * pDest, T * v, memory_order order ) CDS_NOEXCEPT
1094 platform::store_ptr( pDest, v, order );
1096 static void atomic_store( T * volatile * pDest, T * v ) CDS_NOEXCEPT
1098 atomic_store_explicit( pDest, v, memory_order_seq_cst );
1100 static void atomic_store( T * * pDest, T * v ) CDS_NOEXCEPT
1102 atomic_store_explicit( pDest, v, memory_order_seq_cst );
1106 static T * atomic_load_explicit( T * volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
1108 return platform::load_ptr( pSrc, order );
1110 static T * atomic_load_explicit( T * const * pSrc, memory_order order ) CDS_NOEXCEPT
1112 return platform::load_ptr( pSrc, order );
1114 static T * atomic_load( T * volatile const * pSrc ) CDS_NOEXCEPT
1116 return atomic_load_explicit( pSrc, memory_order_seq_cst );
1118 static T * atomic_load( T * const * pSrc ) CDS_NOEXCEPT
1120 return atomic_load_explicit( pSrc, memory_order_seq_cst );
1124 static T * atomic_exchange_explicit( T * volatile * pDest, T * val, memory_order order ) CDS_NOEXCEPT
1126 return platform::exchange_ptr( pDest, val, order );
1128 static T * atomic_exchange_explicit( T * * pDest, T * val, memory_order order ) CDS_NOEXCEPT
1130 return platform::exchange_ptr( pDest, val, order );
1132 static T * atomic_exchange( T * volatile * pDest, T * val ) CDS_NOEXCEPT
1134 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
1136 static T * atomic_exchange( T * * pDest, T * val ) CDS_NOEXCEPT
1138 return atomic_exchange_explicit( pDest, val, memory_order_seq_cst );
1142 static bool atomic_compare_exchange_weak_explicit( T * volatile * pDest, T * * expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
1145 return platform::cas_ptr_weak( pDest, *expected, desired, mo_success, mo_fail );
1147 static bool atomic_compare_exchange_weak_explicit( T * * pDest, T * * expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
1150 return platform::cas_ptr_weak( pDest, *expected, desired, mo_success, mo_fail );
1152 static bool atomic_compare_exchange_weak( T * volatile * pDest, T ** expected, T * desired ) CDS_NOEXCEPT
1154 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
1156 static bool atomic_compare_exchange_weak( T ** pDest, T ** expected, T * desired ) CDS_NOEXCEPT
1158 return atomic_compare_exchange_weak_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
1160 static bool atomic_compare_exchange_strong_explicit( T * volatile * pDest, T ** expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
1163 return platform::cas_ptr_strong( pDest, *expected, desired, mo_success, mo_fail );
1165 static bool atomic_compare_exchange_strong_explicit( T ** pDest, T ** expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
1168 return platform::cas_ptr_strong( pDest, *expected, desired, mo_success, mo_fail );
1170 static bool atomic_compare_exchange_strong( T * volatile * pDest, T ** expected, T * desired ) CDS_NOEXCEPT
1172 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
1174 static bool atomic_compare_exchange_strong( T ** pDest, T ** expected, T * desired ) CDS_NOEXCEPT
1176 return atomic_compare_exchange_strong_explicit( pDest, expected, desired, memory_order_seq_cst, memory_order_relaxed );
1180 template <typename T>
1181 struct atomic_pointer: public atomic_pointer_base<T>
1183 typedef atomic_pointer_base<T> base_class;
1185 static T * atomic_fetch_add_explicit(T * volatile * pDest, ptrdiff_t val, memory_order order) CDS_NOEXCEPT
1187 # ifdef CDS_ATOMIC_fetch_ptr_add_defined
1188 platform::fetch_ptr_add( pDest, val, order );
1190 T * cur = base_class::atomic_load_explicit( pDest, memory_order_relaxed );
1191 do {} while ( !base_class::atomic_compare_exchange_weak_explicit( pDest, &cur, cur + val, order, memory_order_relaxed ));
1195 static T * atomic_fetch_add_explicit(T * * pDest, ptrdiff_t val , memory_order order) CDS_NOEXCEPT
1197 return atomic_fetch_add_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1199 static T * atomic_fetch_add( T * volatile * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1201 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1203 static T * atomic_fetch_add( T ** pDest, ptrdiff_t val ) CDS_NOEXCEPT
1205 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1209 static T * atomic_fetch_sub_explicit(T * volatile * pDest, ptrdiff_t val, memory_order order) CDS_NOEXCEPT
1211 # ifdef CDS_ATOMIC_fetch_ptr_sub_defined
1212 platform::fetch_ptr_sub( pDest, val, order );
1214 T * cur = base_class::atomic_load_explicit( pDest, memory_order_relaxed );
1215 do {} while ( !base_class::atomic_compare_exchange_weak_explicit( pDest, &cur, cur - val, order, memory_order_relaxed ));
1219 static T * atomic_fetch_sub_explicit(T ** pDest, ptrdiff_t val , memory_order order) CDS_NOEXCEPT
1221 return atomic_fetch_sub_explicit( reinterpret_cast<T volatile *>( pDest ), val, order );
1223 static T * atomic_fetch_sub( T volatile * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1225 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1227 static T * atomic_fetch_sub( T * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1229 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1234 struct atomic_pointer<void>: public atomic_pointer_base<void>
1236 typedef atomic_pointer_base<void> base_class;
1239 static void * atomic_fetch_add_explicit(void * volatile * pDest, ptrdiff_t val, memory_order order) CDS_NOEXCEPT
1241 void * cur = base_class::atomic_load_explicit( pDest, memory_order_relaxed );
1242 do {} while ( !base_class::atomic_compare_exchange_weak_explicit( pDest, &cur, reinterpret_cast<char *>(cur) + val, order, memory_order_relaxed ));
1245 static void * atomic_fetch_add_explicit(void * * pDest, ptrdiff_t val , memory_order order) CDS_NOEXCEPT
1247 return atomic_fetch_add_explicit( reinterpret_cast<void * volatile *>( pDest ), val, order );
1249 static void * atomic_fetch_add( void * volatile * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1251 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1253 static void * atomic_fetch_add( void ** pDest, ptrdiff_t val ) CDS_NOEXCEPT
1255 return atomic_fetch_add_explicit( pDest, val, memory_order_seq_cst );
1259 static void * atomic_fetch_sub_explicit(void * volatile * pDest, ptrdiff_t val, memory_order order) CDS_NOEXCEPT
1261 void * cur = base_class::atomic_load_explicit( pDest, memory_order_relaxed );
1262 do {} while ( !base_class::atomic_compare_exchange_weak_explicit( pDest, &cur, reinterpret_cast<char *>(cur) - val, order, memory_order_relaxed ));
1265 static void * atomic_fetch_sub_explicit(void ** pDest, ptrdiff_t val , memory_order order) CDS_NOEXCEPT
1267 return atomic_fetch_sub_explicit( reinterpret_cast<void * volatile *>( pDest ), val, order );
1269 static void * atomic_fetch_sub( void * volatile * pDest, ptrdiff_t val ) CDS_NOEXCEPT
1271 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1273 static void * atomic_fetch_sub( void ** pDest, ptrdiff_t val ) CDS_NOEXCEPT
1275 return atomic_fetch_sub_explicit( pDest, val, memory_order_seq_cst );
1279 #ifndef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1280 class atomic_noncopyable
1283 atomic_noncopyable(const atomic_noncopyable&);
1284 atomic_noncopyable& operator=(const atomic_noncopyable&);
1285 //atomic_noncopyable& operator=(const atomic_noncopyable&) volatile;
1287 atomic_noncopyable() = default;
1291 template <typename T>
1292 struct atomic_integral
1293 #ifndef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1294 : atomic_noncopyable
1298 typename cds::details::aligned_type<T, sizeof(T)>::type volatile m_val;
1300 typedef atomic_integral_ops<T, sizeof(T)> atomic_ops;
1302 typedef T atomic_type;
1304 bool is_lock_free() const volatile CDS_NOEXCEPT
1308 bool is_lock_free() const CDS_NOEXCEPT
1312 void store(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1314 atomic_ops::atomic_store_explicit( &m_val, val, order );
1316 void store(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1318 atomic_ops::atomic_store_explicit( &m_val, val, order );
1321 T load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1323 return atomic_ops::atomic_load_explicit( &m_val, order );
1325 T load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1327 return atomic_ops::atomic_load_explicit( &m_val, order );
1330 operator T() const volatile CDS_NOEXCEPT
1334 operator T() const CDS_NOEXCEPT
1339 T exchange(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1341 return atomic_ops::atomic_exchange_explicit( &m_val, val, order );
1343 T exchange(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1345 return atomic_ops::atomic_exchange_explicit( &m_val, val, order );
1348 bool compare_exchange_weak(T& expected, T desired , memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1350 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_val, &expected, desired, success_order, failure_order );
1352 bool compare_exchange_weak(T& expected, T desired , memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1354 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_val, &expected, desired, success_order, failure_order );
1356 bool compare_exchange_strong(T& expected, T desired , memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1358 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_val, &expected, desired, success_order, failure_order );
1360 bool compare_exchange_strong(T& expected, T desired , memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1362 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_val, &expected, desired, success_order, failure_order );
1364 bool compare_exchange_weak(T& expected, T desired , memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1366 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1368 bool compare_exchange_weak(T& expected, T desired , memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1370 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1372 bool compare_exchange_strong(T& expected, T desired , memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1374 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1376 bool compare_exchange_strong(T& expected, T desired , memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1378 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1381 T fetch_add(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1383 return atomic_ops::atomic_fetch_add_explicit( &m_val, val, order );
1385 T fetch_add(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1387 return atomic_ops::atomic_fetch_add_explicit( &m_val, val, order );
1389 T fetch_sub(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1391 return atomic_ops::atomic_fetch_sub_explicit( &m_val, val, order );
1393 T fetch_sub(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1395 return atomic_ops::atomic_fetch_sub_explicit( &m_val, val, order );
1397 T fetch_and(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1399 return atomic_ops::atomic_fetch_and_explicit( &m_val, val, order );
1401 T fetch_and(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1403 return atomic_ops::atomic_fetch_and_explicit( &m_val, val, order );
1406 T fetch_or(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1408 return atomic_ops::atomic_fetch_or_explicit( &m_val, val, order );
1410 T fetch_or(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1412 return atomic_ops::atomic_fetch_or_explicit( &m_val, val, order );
1414 T fetch_xor(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1416 return atomic_ops::atomic_fetch_xor_explicit( &m_val, val, order );
1418 T fetch_xor(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1420 return atomic_ops::atomic_fetch_xor_explicit( &m_val, val, order );
1423 atomic_integral() = default;
1424 CDS_CONSTEXPR atomic_integral(T val) CDS_NOEXCEPT
1428 #ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1429 atomic_integral(const atomic_integral&) = delete;
1430 atomic_integral& operator=(const atomic_integral&) = delete;
1431 atomic_integral& operator=(const atomic_integral&) volatile = delete;
1433 T operator=(T val) volatile CDS_NOEXCEPT
1438 T operator=(T val) CDS_NOEXCEPT
1445 T operator++(int) volatile CDS_NOEXCEPT
1447 return fetch_add( 1 );
1449 T operator++(int) CDS_NOEXCEPT
1451 return fetch_add( 1 );
1453 T operator--(int) volatile CDS_NOEXCEPT
1455 return fetch_sub( 1 );
1457 T operator--(int) CDS_NOEXCEPT
1459 return fetch_sub( 1 );
1463 T operator++() volatile CDS_NOEXCEPT
1465 return fetch_add( 1 ) + 1;
1467 T operator++() CDS_NOEXCEPT
1469 return fetch_add( 1 ) + 1;
1471 T operator--() volatile CDS_NOEXCEPT
1473 return fetch_sub( 1 ) - 1;
1475 T operator--() CDS_NOEXCEPT
1477 return fetch_sub( 1 ) - 1;
1481 T operator+=(T val) volatile CDS_NOEXCEPT
1483 return fetch_add( val ) + val;
1485 T operator+=(T val) CDS_NOEXCEPT
1487 return fetch_add( val ) + val;
1489 T operator-=(T val) volatile CDS_NOEXCEPT
1491 return fetch_sub( val ) - val;
1493 T operator-=(T val) CDS_NOEXCEPT
1495 return fetch_sub( val ) - val;
1497 T operator&=(T val) volatile CDS_NOEXCEPT
1499 return fetch_and( val ) & val;
1501 T operator&=(T val) CDS_NOEXCEPT
1503 return fetch_and( val ) & val;
1505 T operator|=(T val) volatile CDS_NOEXCEPT
1507 return fetch_or( val ) | val;
1509 T operator|=(T val) CDS_NOEXCEPT
1511 return fetch_or( val ) | val;
1513 T operator^=(T val) volatile CDS_NOEXCEPT
1515 return fetch_xor( val ) ^ val;
1517 T operator^=(T val) CDS_NOEXCEPT
1519 return fetch_xor( val ) ^ val;
1523 template <typename Type>
1524 struct select_primary_type {
1525 typedef typename details::primary_type<sizeof(Type)>::type type;
1528 struct select_primary_type<bool> {
1532 } // namespace details
1536 #ifndef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1537 : details::atomic_noncopyable
1541 typedef details::atomic_generic_ops<T, sizeof(T), typename details::select_primary_type<T>::type > atomic_ops;
1545 bool is_lock_free() const volatile CDS_NOEXCEPT
1549 bool is_lock_free() const CDS_NOEXCEPT
1554 void store(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1556 atomic_ops::atomic_store_explicit( &m_data, val, order );
1558 void store(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1560 atomic_ops::atomic_store_explicit( &m_data, val, order );
1563 T load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1565 return atomic_ops::atomic_load_explicit( &m_data, order );
1567 T load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1569 return atomic_ops::atomic_load_explicit( &m_data, order );
1572 operator T() const volatile CDS_NOEXCEPT
1576 operator T() const CDS_NOEXCEPT
1581 T exchange(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1583 return atomic_ops::atomic_exchange_explicit( &m_data, val, order );
1585 T exchange(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1587 return atomic_ops::atomic_exchange_explicit( &m_data, val, order );
1590 bool compare_exchange_weak(T& expected, T desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1592 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_data, &expected, desired, success_order, failure_order );
1594 bool compare_exchange_weak(T& expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1596 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_data, &expected, desired, success_order, failure_order );
1598 bool compare_exchange_strong(T& expected, T desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1600 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_data, &expected, desired, success_order, failure_order );
1602 bool compare_exchange_strong(T& expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1604 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_data, &expected, desired, success_order, failure_order );
1606 bool compare_exchange_weak(T& expected, T desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1608 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1610 bool compare_exchange_weak(T& expected, T desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1612 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1614 bool compare_exchange_strong(T& expected, T desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1616 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1618 bool compare_exchange_strong(T& expected, T desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1620 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1624 CDS_CONSTEXPR atomic(T val)
1628 #ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1629 atomic(const atomic&) = delete;
1630 atomic& operator=(const atomic&) = delete;
1631 atomic& operator=(const atomic&) volatile = delete;
1634 T operator=(T val) volatile CDS_NOEXCEPT
1639 T operator=(T val) CDS_NOEXCEPT
1646 #if defined(CDS_CXX11_DELETE_DEFINITION_SUPPORT)
1647 # define CDS_DECLARE_ATOMIC_INTEGRAL( _type ) \
1649 struct atomic<_type>: public details::atomic_integral<_type> \
1652 typedef details::atomic_integral<_type> base_class ; \
1654 atomic() = default; \
1655 atomic(_type val) CDS_NOEXCEPT : base_class(val) {} \
1656 atomic(const atomic&) = delete; \
1657 atomic& operator=(const atomic&) = delete; \
1658 atomic& operator=(const atomic&) volatile = delete; \
1659 _type operator=(_type val) volatile CDS_NOEXCEPT { return base_class::operator=(val); } \
1660 _type operator=(_type val) CDS_NOEXCEPT { return base_class::operator=(val); } \
1663 # define CDS_DECLARE_ATOMIC_INTEGRAL( _type ) \
1665 struct atomic<_type>: public details::atomic_integral<_type> \
1668 typedef details::atomic_integral<_type> base_class ; \
1671 atomic(_type val) CDS_NOEXCEPT : base_class(val) {} \
1672 _type operator=(_type val) volatile CDS_NOEXCEPT { return base_class::operator=(val); } \
1673 _type operator=(_type val) CDS_NOEXCEPT { return base_class::operator=(val); } \
1677 CDS_DECLARE_ATOMIC_INTEGRAL(char)
1678 CDS_DECLARE_ATOMIC_INTEGRAL(signed char)
1679 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned char)
1680 CDS_DECLARE_ATOMIC_INTEGRAL(short)
1681 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned short)
1682 CDS_DECLARE_ATOMIC_INTEGRAL(int)
1683 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned int)
1684 CDS_DECLARE_ATOMIC_INTEGRAL(long)
1685 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned long)
1686 CDS_DECLARE_ATOMIC_INTEGRAL(long long)
1687 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned long long)
1688 //#if CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40400
1689 // CDS_DECLARE_ATOMIC_INTEGRAL(char16_t)
1690 // CDS_DECLARE_ATOMIC_INTEGRAL(char32_t)
1692 // CDS_DECLARE_ATOMIC_INTEGRAL(wchar_t)
1694 # undef CDS_DECLARE_ATOMIC_INTEGRAL
1697 template <typename T>
1699 #ifndef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1700 : details::atomic_noncopyable
1705 typedef details::atomic_pointer<T> atomic_ops;
1707 bool is_lock_free() const volatile CDS_NOEXCEPT
1711 bool is_lock_free() const CDS_NOEXCEPT
1716 void store(T * val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1718 atomic_ops::atomic_store_explicit( &m_ptr, val, order );
1720 void store(T * val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1722 atomic_ops::atomic_store_explicit( &m_ptr, val, order );
1725 T * load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1727 return atomic_ops::atomic_load_explicit( &m_ptr, order );
1729 T * load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1731 return atomic_ops::atomic_load_explicit( &m_ptr, order );
1734 operator T *() const volatile CDS_NOEXCEPT
1738 operator T *() const CDS_NOEXCEPT
1743 T * exchange(T * val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1745 return atomic_ops::atomic_exchange_explicit( &m_ptr, val, order );
1747 T * exchange(T * val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1749 return atomic_ops::atomic_exchange_explicit( &m_ptr, val, order );
1752 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1754 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1756 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1758 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1760 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1762 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1764 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1766 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1768 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1770 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1772 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1774 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1776 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1778 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1780 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1782 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1785 T * fetch_add(ptrdiff_t offset, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1787 return atomic_ops::atomic_fetch_add_explicit( &m_ptr, offset, order );
1789 T * fetch_add(ptrdiff_t offset, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1791 return atomic_ops::atomic_fetch_add_explicit( &m_ptr, offset, order );
1794 T * fetch_sub(ptrdiff_t offset, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1796 return atomic_ops::atomic_fetch_sub_explicit( &m_ptr, offset, order );
1798 T * fetch_sub(ptrdiff_t offset, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1800 return atomic_ops::atomic_fetch_sub_explicit( &m_ptr, offset, order );
1804 CDS_CONSTEXPR atomic(T * val) CDS_NOEXCEPT
1808 #ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1809 atomic(const atomic&) = delete;
1810 atomic& operator=(const atomic&) = delete;
1811 atomic& operator=(const atomic&) volatile = delete;
1814 T * operator=(T * val) volatile CDS_NOEXCEPT
1819 T * operator=(T * val) CDS_NOEXCEPT
1827 typedef atomic<bool> atomic_bool;
1828 typedef atomic<char> atomic_char;
1829 typedef atomic<signed char> atomic_schar;
1830 typedef atomic<unsigned char> atomic_uchar;
1831 typedef atomic<short> atomic_short;
1832 typedef atomic<unsigned short> atomic_ushort;
1833 typedef atomic<int> atomic_int;
1834 typedef atomic<unsigned int> atomic_uint;
1835 typedef atomic<long> atomic_long;
1836 typedef atomic<unsigned long> atomic_ulong;
1837 typedef atomic<long long> atomic_llong;
1838 typedef atomic<unsigned long long> atomic_ullong;
1839 #if ( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40400 ) || CDS_COMPILER == CDS_COMPILER_CLANG
1840 typedef atomic<char16_t> atomic_char16_t;
1841 typedef atomic<char32_t> atomic_char32_t;
1843 typedef atomic<wchar_t> atomic_wchar_t;
1846 typedef atomic<cds::int_least8_t> atomic_int_least8_t;
1847 typedef atomic<cds::uint_least8_t> atomic_uint_least8_t;
1848 typedef atomic<cds::int_least16_t> atomic_int_least16_t;
1849 typedef atomic<cds::uint_least16_t> atomic_uint_least16_t;
1850 typedef atomic<cds::int_least32_t> atomic_int_least32_t;
1851 typedef atomic<cds::uint_least32_t> atomic_uint_least32_t;
1852 typedef atomic<cds::int_least64_t> atomic_int_least64_t;
1853 typedef atomic<cds::uint_least64_t> atomic_uint_least64_t;
1854 typedef atomic<cds::int_fast8_t> atomic_int_fast8_t;
1855 typedef atomic<cds::uint_fast8_t> atomic_uint_fast8_t;
1856 typedef atomic<cds::int_fast16_t> atomic_int_fast16_t;
1857 typedef atomic<cds::uint_fast16_t> atomic_uint_fast16_t;
1858 typedef atomic<cds::int_fast32_t> atomic_int_fast32_t;
1859 typedef atomic<cds::uint_fast32_t> atomic_uint_fast32_t;
1860 typedef atomic<cds::int_fast64_t> atomic_int_fast64_t;
1861 typedef atomic<cds::uint_fast64_t> atomic_uint_fast64_t;
1862 typedef atomic<intptr_t> atomic_intptr_t;
1863 typedef atomic<uintptr_t> atomic_uintptr_t;
1864 typedef atomic<size_t> atomic_size_t;
1865 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1866 typedef atomic<cds::intmax_t> atomic_intmax_t;
1867 typedef atomic<cds::uintmax_t> atomic_uintmax_t;
1870 static inline bool atomic_is_lock_free(const volatile atomic<T> * p) CDS_NOEXCEPT
1872 return p->is_lock_free();
1876 static inline bool atomic_is_lock_free(const atomic<T> * p ) CDS_NOEXCEPT
1878 return p->is_lock_free();
1883 static inline void atomic_init(volatile atomic<T> * p, T val) CDS_NOEXCEPT
1889 static inline void atomic_init( atomic<T> * p, T val) CDS_NOEXCEPT
1896 static inline void atomic_store(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1901 static inline void atomic_store(atomic<T>* p, T val) CDS_NOEXCEPT
1907 static inline void atomic_store_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1909 p->store( val, order );
1912 static inline void atomic_store_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1914 p->store( val, order );
1918 static inline T atomic_load(const volatile atomic<T>* p) CDS_NOEXCEPT
1923 static inline T atomic_load(const atomic<T>* p) CDS_NOEXCEPT
1929 static inline T atomic_load_explicit(const volatile atomic<T>* p, memory_order order) CDS_NOEXCEPT
1931 return p->load( order );
1934 static inline T atomic_load_explicit(const atomic<T>* p, memory_order order) CDS_NOEXCEPT
1936 return p->load( order );
1940 static inline T atomic_exchange(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1942 return p->exchange( val );
1945 static inline T atomic_exchange(atomic<T>* p, T val ) CDS_NOEXCEPT
1947 return p->exchange( val );
1951 static inline T atomic_exchange_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1953 return p->exchange( val, order );
1956 static inline T atomic_exchange_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1958 return p->exchange( val, order );
1962 static inline bool atomic_compare_exchange_weak(volatile atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1964 return p->compare_exchange_weak( *expected, desired );
1967 static inline bool atomic_compare_exchange_weak(atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1969 return p->compare_exchange_weak( *expected, desired );
1973 static inline bool atomic_compare_exchange_strong(volatile atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1975 return p->compare_exchange_strong( *expected, desired );
1978 static inline bool atomic_compare_exchange_strong(atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1980 return p->compare_exchange_strong( *expected, desired );
1984 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
1986 return p->compare_exchange_weak( *expected, desired, success_order, failure_order );
1989 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
1991 return p->compare_exchange_weak( *expected, desired, success_order, failure_order );
1995 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
1997 return p->compare_exchange_strong( *expected, desired, success_order, failure_order );
2000 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
2002 return p->compare_exchange_strong( *expected, desired, success_order, failure_order );
2006 static inline T atomic_fetch_add(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2008 return p->fetch_add( val );
2011 static inline T atomic_fetch_add(atomic<T>* p, T val) CDS_NOEXCEPT
2013 return p->fetch_add( val );
2016 static inline T * atomic_fetch_add(volatile atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2018 return p->fetch_add( offset );
2021 static inline T * atomic_fetch_add(atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2023 return p->fetch_add( offset );
2027 static inline T atomic_fetch_add_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2029 return p->fetch_add( val, order );
2032 static inline T atomic_fetch_add_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2034 return p->fetch_add( val, order );
2037 static inline T * atomic_fetch_add_explicit(volatile atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2039 return p->fetch_add( offset, order );
2042 static inline T * atomic_fetch_add_explicit(atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2044 return p->fetch_add( offset, order );
2048 static inline T atomic_fetch_sub(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2050 return p->fetch_sub( val );
2053 static inline T atomic_fetch_sub(atomic<T>* p, T val) CDS_NOEXCEPT
2055 return p->fetch_sub( val );
2058 static inline T * atomic_fetch_sub(volatile atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2060 return p->fetch_sub( offset );
2063 static inline T * atomic_fetch_sub(atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2065 return p->fetch_sub( offset );
2069 static inline T atomic_fetch_sub_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2071 return p->fetch_sub( val, order );
2074 static inline T atomic_fetch_sub_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2076 return p->fetch_sub( val, order );
2079 static inline T * atomic_fetch_sub_explicit(volatile atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2081 return p->fetch_sub( offset, order );
2084 static inline T * atomic_fetch_sub_explicit(atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2086 return p->fetch_sub( offset, order );
2090 static inline T atomic_fetch_and(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2092 return p->fetch_and( val );
2095 static inline T atomic_fetch_and(atomic<T>* p, T val) CDS_NOEXCEPT
2097 return p->fetch_and( val );
2101 static inline T atomic_fetch_and_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2103 return p->fetch_and( val, order );
2106 static inline T atomic_fetch_and_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2108 return p->fetch_and( val, order );
2112 static inline T atomic_fetch_or(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2114 return p->fetch_or( val );
2117 static inline T atomic_fetch_or(atomic<T>* p, T val) CDS_NOEXCEPT
2119 return p->fetch_or( val );
2123 static inline T atomic_fetch_or_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2125 return p->fetch_or( val, order );
2128 static inline T atomic_fetch_or_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2130 return p->fetch_or( val, order );
2134 static inline T atomic_fetch_xor(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2136 return p->fetch_xor( val );
2139 static inline T atomic_fetch_xor(atomic<T>* p, T val) CDS_NOEXCEPT
2141 return p->fetch_xor( val );
2145 static inline T atomic_fetch_xor_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2147 return p->fetch_xor( val, order );
2150 static inline T atomic_fetch_xor_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2152 return p->fetch_xor( val, order );
2156 typedef struct atomic_flag
2158 void clear( memory_order order = memory_order_seq_cst ) volatile CDS_NOEXCEPT
2160 assert( order != memory_order_acquire
2161 && order != memory_order_acq_rel
2162 && order != memory_order_consume
2164 platform::atomic_flag_clear( &m_Flag, order );
2166 void clear( memory_order order = memory_order_seq_cst ) CDS_NOEXCEPT
2168 assert( order != memory_order_acquire
2169 && order != memory_order_acq_rel
2170 && order != memory_order_consume
2172 platform::atomic_flag_clear( &m_Flag, order );
2175 bool test_and_set( memory_order order = memory_order_seq_cst ) volatile CDS_NOEXCEPT
2177 return platform::atomic_flag_tas( &m_Flag, order );
2179 bool test_and_set( memory_order order = memory_order_seq_cst ) CDS_NOEXCEPT
2181 return platform::atomic_flag_tas( &m_Flag, order );
2184 atomic_flag() = default;
2186 #ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
2187 atomic_flag(const atomic_flag&) = delete;
2188 atomic_flag& operator=(const atomic_flag&) = delete;
2189 atomic_flag& operator=(const atomic_flag&) volatile = delete;
2190 #elif CDS_COMPILER != CDS_COMPILER_MSVC
2191 // MS VC generate error C2552 "non-aggregates cannot be initialized with initializer list"
2192 // when atomic_flag initializes with ATOMIC_FLAG_INIT
2194 atomic_flag(const atomic_flag&);
2195 atomic_flag& operator=(const atomic_flag&);
2196 atomic_flag& operator=(const atomic_flag&) volatile;
2200 platform::atomic_flag_type volatile m_Flag;
2203 static inline bool atomic_flag_test_and_set(volatile atomic_flag* p) CDS_NOEXCEPT
2205 return p->test_and_set();
2207 static inline bool atomic_flag_test_and_set(atomic_flag * p) CDS_NOEXCEPT
2209 return p->test_and_set();
2211 static inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag* p, memory_order order) CDS_NOEXCEPT
2213 return p->test_and_set( order );
2215 static inline bool atomic_flag_test_and_set_explicit(atomic_flag* p, memory_order order) CDS_NOEXCEPT
2217 return p->test_and_set( order );
2219 static inline void atomic_flag_clear(volatile atomic_flag* p) CDS_NOEXCEPT
2223 static inline void atomic_flag_clear(atomic_flag* p) CDS_NOEXCEPT
2227 static inline void atomic_flag_clear_explicit(volatile atomic_flag* p, memory_order order) CDS_NOEXCEPT
2229 return p->clear( order );
2231 static inline void atomic_flag_clear_explicit(atomic_flag* p, memory_order order) CDS_NOEXCEPT
2233 return p->clear( order );
2237 static inline void atomic_thread_fence(memory_order order) CDS_NOEXCEPT
2239 platform::thread_fence( order );
2240 CDS_COMPILER_RW_BARRIER;
2242 static inline void atomic_signal_fence(memory_order order) CDS_NOEXCEPT
2244 platform::signal_fence( order );
2247 }} // namespace cds::cxx11_atomic
2250 #endif // #ifndef __CDS_COMPILER_CXX11_ATOMIC_H