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 template <typename T>
1280 struct atomic_integral
1283 typename cds::details::aligned_type<T, sizeof(T)>::type volatile m_val;
1285 typedef atomic_integral_ops<T, sizeof(T)> atomic_ops;
1287 typedef T atomic_type;
1289 bool is_lock_free() const volatile CDS_NOEXCEPT
1293 bool is_lock_free() const CDS_NOEXCEPT
1297 void store(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1299 atomic_ops::atomic_store_explicit( &m_val, val, order );
1301 void store(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1303 atomic_ops::atomic_store_explicit( &m_val, val, order );
1306 T load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1308 return atomic_ops::atomic_load_explicit( &m_val, order );
1310 T load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1312 return atomic_ops::atomic_load_explicit( &m_val, order );
1315 operator T() const volatile CDS_NOEXCEPT
1319 operator T() const CDS_NOEXCEPT
1324 T exchange(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1326 return atomic_ops::atomic_exchange_explicit( &m_val, val, order );
1328 T exchange(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1330 return atomic_ops::atomic_exchange_explicit( &m_val, val, order );
1333 bool compare_exchange_weak(T& expected, T desired , memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1335 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_val, &expected, desired, success_order, failure_order );
1337 bool compare_exchange_weak(T& expected, T desired , memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1339 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_val, &expected, desired, success_order, failure_order );
1341 bool compare_exchange_strong(T& expected, T desired , memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1343 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_val, &expected, desired, success_order, failure_order );
1345 bool compare_exchange_strong(T& expected, T desired , memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1347 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_val, &expected, desired, success_order, failure_order );
1349 bool compare_exchange_weak(T& expected, T desired , memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1351 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1353 bool compare_exchange_weak(T& expected, T desired , memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1355 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1357 bool compare_exchange_strong(T& expected, T desired , memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1359 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1361 bool compare_exchange_strong(T& expected, T desired , memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1363 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1366 T fetch_add(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1368 return atomic_ops::atomic_fetch_add_explicit( &m_val, val, order );
1370 T fetch_add(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1372 return atomic_ops::atomic_fetch_add_explicit( &m_val, val, order );
1374 T fetch_sub(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1376 return atomic_ops::atomic_fetch_sub_explicit( &m_val, val, order );
1378 T fetch_sub(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1380 return atomic_ops::atomic_fetch_sub_explicit( &m_val, val, order );
1382 T fetch_and(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1384 return atomic_ops::atomic_fetch_and_explicit( &m_val, val, order );
1386 T fetch_and(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1388 return atomic_ops::atomic_fetch_and_explicit( &m_val, val, order );
1391 T fetch_or(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1393 return atomic_ops::atomic_fetch_or_explicit( &m_val, val, order );
1395 T fetch_or(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1397 return atomic_ops::atomic_fetch_or_explicit( &m_val, val, order );
1399 T fetch_xor(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1401 return atomic_ops::atomic_fetch_xor_explicit( &m_val, val, order );
1403 T fetch_xor(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1405 return atomic_ops::atomic_fetch_xor_explicit( &m_val, val, order );
1408 atomic_integral() = default;
1409 CDS_CONSTEXPR atomic_integral(T val) CDS_NOEXCEPT
1413 atomic_integral(const atomic_integral&) = delete;
1414 atomic_integral& operator=(const atomic_integral&) = delete;
1415 atomic_integral& operator=(const atomic_integral&) volatile = delete;
1417 T operator=(T val) volatile CDS_NOEXCEPT
1422 T operator=(T val) CDS_NOEXCEPT
1429 T operator++(int) volatile CDS_NOEXCEPT
1431 return fetch_add( 1 );
1433 T operator++(int) CDS_NOEXCEPT
1435 return fetch_add( 1 );
1437 T operator--(int) volatile CDS_NOEXCEPT
1439 return fetch_sub( 1 );
1441 T operator--(int) CDS_NOEXCEPT
1443 return fetch_sub( 1 );
1447 T operator++() volatile CDS_NOEXCEPT
1449 return fetch_add( 1 ) + 1;
1451 T operator++() CDS_NOEXCEPT
1453 return fetch_add( 1 ) + 1;
1455 T operator--() volatile CDS_NOEXCEPT
1457 return fetch_sub( 1 ) - 1;
1459 T operator--() CDS_NOEXCEPT
1461 return fetch_sub( 1 ) - 1;
1465 T operator+=(T val) volatile CDS_NOEXCEPT
1467 return fetch_add( val ) + val;
1469 T operator+=(T val) CDS_NOEXCEPT
1471 return fetch_add( val ) + val;
1473 T operator-=(T val) volatile CDS_NOEXCEPT
1475 return fetch_sub( val ) - val;
1477 T operator-=(T val) CDS_NOEXCEPT
1479 return fetch_sub( val ) - val;
1481 T operator&=(T val) volatile CDS_NOEXCEPT
1483 return fetch_and( val ) & val;
1485 T operator&=(T val) CDS_NOEXCEPT
1487 return fetch_and( val ) & val;
1489 T operator|=(T val) volatile CDS_NOEXCEPT
1491 return fetch_or( val ) | val;
1493 T operator|=(T val) CDS_NOEXCEPT
1495 return fetch_or( val ) | val;
1497 T operator^=(T val) volatile CDS_NOEXCEPT
1499 return fetch_xor( val ) ^ val;
1501 T operator^=(T val) CDS_NOEXCEPT
1503 return fetch_xor( val ) ^ val;
1507 template <typename Type>
1508 struct select_primary_type {
1509 typedef typename details::primary_type<sizeof(Type)>::type type;
1512 struct select_primary_type<bool> {
1516 } // namespace details
1522 typedef details::atomic_generic_ops<T, sizeof(T), typename details::select_primary_type<T>::type > atomic_ops;
1526 bool is_lock_free() const volatile CDS_NOEXCEPT
1530 bool is_lock_free() const CDS_NOEXCEPT
1535 void store(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1537 atomic_ops::atomic_store_explicit( &m_data, val, order );
1539 void store(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1541 atomic_ops::atomic_store_explicit( &m_data, val, order );
1544 T load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1546 return atomic_ops::atomic_load_explicit( &m_data, order );
1548 T load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1550 return atomic_ops::atomic_load_explicit( &m_data, order );
1553 operator T() const volatile CDS_NOEXCEPT
1557 operator T() const CDS_NOEXCEPT
1562 T exchange(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1564 return atomic_ops::atomic_exchange_explicit( &m_data, val, order );
1566 T exchange(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1568 return atomic_ops::atomic_exchange_explicit( &m_data, val, order );
1571 bool compare_exchange_weak(T& expected, T desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1573 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_data, &expected, desired, success_order, failure_order );
1575 bool compare_exchange_weak(T& expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1577 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_data, &expected, desired, success_order, failure_order );
1579 bool compare_exchange_strong(T& expected, T desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1581 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_data, &expected, desired, success_order, failure_order );
1583 bool compare_exchange_strong(T& expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1585 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_data, &expected, desired, success_order, failure_order );
1587 bool compare_exchange_weak(T& expected, T desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1589 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1591 bool compare_exchange_weak(T& expected, T desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1593 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1595 bool compare_exchange_strong(T& expected, T desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1597 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1599 bool compare_exchange_strong(T& expected, T desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1601 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1605 CDS_CONSTEXPR atomic(T val)
1609 atomic(const atomic&) = delete;
1610 atomic& operator=(const atomic&) = delete;
1611 atomic& operator=(const atomic&) volatile = delete;
1613 T operator=(T val) volatile CDS_NOEXCEPT
1618 T operator=(T val) CDS_NOEXCEPT
1625 # define CDS_DECLARE_ATOMIC_INTEGRAL( _type ) \
1627 struct atomic<_type>: public details::atomic_integral<_type> \
1630 typedef details::atomic_integral<_type> base_class ; \
1632 atomic() = default; \
1633 atomic(_type val) CDS_NOEXCEPT : base_class(val) {} \
1634 atomic(const atomic&) = delete; \
1635 atomic& operator=(const atomic&) = delete; \
1636 atomic& operator=(const atomic&) volatile = delete; \
1637 _type operator=(_type val) volatile CDS_NOEXCEPT { return base_class::operator=(val); } \
1638 _type operator=(_type val) CDS_NOEXCEPT { return base_class::operator=(val); } \
1641 CDS_DECLARE_ATOMIC_INTEGRAL(char)
1642 CDS_DECLARE_ATOMIC_INTEGRAL(signed char)
1643 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned char)
1644 CDS_DECLARE_ATOMIC_INTEGRAL(short)
1645 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned short)
1646 CDS_DECLARE_ATOMIC_INTEGRAL(int)
1647 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned int)
1648 CDS_DECLARE_ATOMIC_INTEGRAL(long)
1649 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned long)
1650 CDS_DECLARE_ATOMIC_INTEGRAL(long long)
1651 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned long long)
1652 //#if CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40400
1653 // CDS_DECLARE_ATOMIC_INTEGRAL(char16_t)
1654 // CDS_DECLARE_ATOMIC_INTEGRAL(char32_t)
1656 // CDS_DECLARE_ATOMIC_INTEGRAL(wchar_t)
1658 # undef CDS_DECLARE_ATOMIC_INTEGRAL
1661 template <typename T>
1666 typedef details::atomic_pointer<T> atomic_ops;
1668 bool is_lock_free() const volatile CDS_NOEXCEPT
1672 bool is_lock_free() const CDS_NOEXCEPT
1677 void store(T * val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1679 atomic_ops::atomic_store_explicit( &m_ptr, val, order );
1681 void store(T * val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1683 atomic_ops::atomic_store_explicit( &m_ptr, val, order );
1686 T * load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1688 return atomic_ops::atomic_load_explicit( &m_ptr, order );
1690 T * load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1692 return atomic_ops::atomic_load_explicit( &m_ptr, order );
1695 operator T *() const volatile CDS_NOEXCEPT
1699 operator T *() const CDS_NOEXCEPT
1704 T * exchange(T * val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1706 return atomic_ops::atomic_exchange_explicit( &m_ptr, val, order );
1708 T * exchange(T * val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1710 return atomic_ops::atomic_exchange_explicit( &m_ptr, val, order );
1713 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1715 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1717 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1719 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1721 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1723 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1725 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1727 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1729 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1731 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1733 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1735 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1737 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1739 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1741 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1743 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1746 T * fetch_add(ptrdiff_t offset, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1748 return atomic_ops::atomic_fetch_add_explicit( &m_ptr, offset, order );
1750 T * fetch_add(ptrdiff_t offset, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1752 return atomic_ops::atomic_fetch_add_explicit( &m_ptr, offset, order );
1755 T * fetch_sub(ptrdiff_t offset, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1757 return atomic_ops::atomic_fetch_sub_explicit( &m_ptr, offset, order );
1759 T * fetch_sub(ptrdiff_t offset, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1761 return atomic_ops::atomic_fetch_sub_explicit( &m_ptr, offset, order );
1765 CDS_CONSTEXPR atomic(T * val) CDS_NOEXCEPT
1769 atomic(const atomic&) = delete;
1770 atomic& operator=(const atomic&) = delete;
1771 atomic& operator=(const atomic&) volatile = delete;
1773 T * operator=(T * val) volatile CDS_NOEXCEPT
1778 T * operator=(T * val) CDS_NOEXCEPT
1786 typedef atomic<bool> atomic_bool;
1787 typedef atomic<char> atomic_char;
1788 typedef atomic<signed char> atomic_schar;
1789 typedef atomic<unsigned char> atomic_uchar;
1790 typedef atomic<short> atomic_short;
1791 typedef atomic<unsigned short> atomic_ushort;
1792 typedef atomic<int> atomic_int;
1793 typedef atomic<unsigned int> atomic_uint;
1794 typedef atomic<long> atomic_long;
1795 typedef atomic<unsigned long> atomic_ulong;
1796 typedef atomic<long long> atomic_llong;
1797 typedef atomic<unsigned long long> atomic_ullong;
1798 #if ( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40400 ) || CDS_COMPILER == CDS_COMPILER_CLANG
1799 typedef atomic<char16_t> atomic_char16_t;
1800 typedef atomic<char32_t> atomic_char32_t;
1802 typedef atomic<wchar_t> atomic_wchar_t;
1805 typedef atomic<cds::int_least8_t> atomic_int_least8_t;
1806 typedef atomic<cds::uint_least8_t> atomic_uint_least8_t;
1807 typedef atomic<cds::int_least16_t> atomic_int_least16_t;
1808 typedef atomic<cds::uint_least16_t> atomic_uint_least16_t;
1809 typedef atomic<cds::int_least32_t> atomic_int_least32_t;
1810 typedef atomic<cds::uint_least32_t> atomic_uint_least32_t;
1811 typedef atomic<cds::int_least64_t> atomic_int_least64_t;
1812 typedef atomic<cds::uint_least64_t> atomic_uint_least64_t;
1813 typedef atomic<cds::int_fast8_t> atomic_int_fast8_t;
1814 typedef atomic<cds::uint_fast8_t> atomic_uint_fast8_t;
1815 typedef atomic<cds::int_fast16_t> atomic_int_fast16_t;
1816 typedef atomic<cds::uint_fast16_t> atomic_uint_fast16_t;
1817 typedef atomic<cds::int_fast32_t> atomic_int_fast32_t;
1818 typedef atomic<cds::uint_fast32_t> atomic_uint_fast32_t;
1819 typedef atomic<cds::int_fast64_t> atomic_int_fast64_t;
1820 typedef atomic<cds::uint_fast64_t> atomic_uint_fast64_t;
1821 typedef atomic<intptr_t> atomic_intptr_t;
1822 typedef atomic<uintptr_t> atomic_uintptr_t;
1823 typedef atomic<size_t> atomic_size_t;
1824 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1825 typedef atomic<cds::intmax_t> atomic_intmax_t;
1826 typedef atomic<cds::uintmax_t> atomic_uintmax_t;
1829 static inline bool atomic_is_lock_free(const volatile atomic<T> * p) CDS_NOEXCEPT
1831 return p->is_lock_free();
1835 static inline bool atomic_is_lock_free(const atomic<T> * p ) CDS_NOEXCEPT
1837 return p->is_lock_free();
1842 static inline void atomic_init(volatile atomic<T> * p, T val) CDS_NOEXCEPT
1848 static inline void atomic_init( atomic<T> * p, T val) CDS_NOEXCEPT
1855 static inline void atomic_store(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1860 static inline void atomic_store(atomic<T>* p, T val) CDS_NOEXCEPT
1866 static inline void atomic_store_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1868 p->store( val, order );
1871 static inline void atomic_store_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1873 p->store( val, order );
1877 static inline T atomic_load(const volatile atomic<T>* p) CDS_NOEXCEPT
1882 static inline T atomic_load(const atomic<T>* p) CDS_NOEXCEPT
1888 static inline T atomic_load_explicit(const volatile atomic<T>* p, memory_order order) CDS_NOEXCEPT
1890 return p->load( order );
1893 static inline T atomic_load_explicit(const atomic<T>* p, memory_order order) CDS_NOEXCEPT
1895 return p->load( order );
1899 static inline T atomic_exchange(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1901 return p->exchange( val );
1904 static inline T atomic_exchange(atomic<T>* p, T val ) CDS_NOEXCEPT
1906 return p->exchange( val );
1910 static inline T atomic_exchange_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1912 return p->exchange( val, order );
1915 static inline T atomic_exchange_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1917 return p->exchange( val, order );
1921 static inline bool atomic_compare_exchange_weak(volatile atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1923 return p->compare_exchange_weak( *expected, desired );
1926 static inline bool atomic_compare_exchange_weak(atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1928 return p->compare_exchange_weak( *expected, desired );
1932 static inline bool atomic_compare_exchange_strong(volatile atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1934 return p->compare_exchange_strong( *expected, desired );
1937 static inline bool atomic_compare_exchange_strong(atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1939 return p->compare_exchange_strong( *expected, desired );
1943 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
1945 return p->compare_exchange_weak( *expected, desired, success_order, failure_order );
1948 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
1950 return p->compare_exchange_weak( *expected, desired, success_order, failure_order );
1954 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
1956 return p->compare_exchange_strong( *expected, desired, success_order, failure_order );
1959 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
1961 return p->compare_exchange_strong( *expected, desired, success_order, failure_order );
1965 static inline T atomic_fetch_add(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1967 return p->fetch_add( val );
1970 static inline T atomic_fetch_add(atomic<T>* p, T val) CDS_NOEXCEPT
1972 return p->fetch_add( val );
1975 static inline T * atomic_fetch_add(volatile atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
1977 return p->fetch_add( offset );
1980 static inline T * atomic_fetch_add(atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
1982 return p->fetch_add( offset );
1986 static inline T atomic_fetch_add_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1988 return p->fetch_add( val, order );
1991 static inline T atomic_fetch_add_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1993 return p->fetch_add( val, order );
1996 static inline T * atomic_fetch_add_explicit(volatile atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
1998 return p->fetch_add( offset, order );
2001 static inline T * atomic_fetch_add_explicit(atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2003 return p->fetch_add( offset, order );
2007 static inline T atomic_fetch_sub(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2009 return p->fetch_sub( val );
2012 static inline T atomic_fetch_sub(atomic<T>* p, T val) CDS_NOEXCEPT
2014 return p->fetch_sub( val );
2017 static inline T * atomic_fetch_sub(volatile atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2019 return p->fetch_sub( offset );
2022 static inline T * atomic_fetch_sub(atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2024 return p->fetch_sub( offset );
2028 static inline T atomic_fetch_sub_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2030 return p->fetch_sub( val, order );
2033 static inline T atomic_fetch_sub_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2035 return p->fetch_sub( val, order );
2038 static inline T * atomic_fetch_sub_explicit(volatile atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2040 return p->fetch_sub( offset, order );
2043 static inline T * atomic_fetch_sub_explicit(atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2045 return p->fetch_sub( offset, order );
2049 static inline T atomic_fetch_and(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2051 return p->fetch_and( val );
2054 static inline T atomic_fetch_and(atomic<T>* p, T val) CDS_NOEXCEPT
2056 return p->fetch_and( val );
2060 static inline T atomic_fetch_and_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2062 return p->fetch_and( val, order );
2065 static inline T atomic_fetch_and_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2067 return p->fetch_and( val, order );
2071 static inline T atomic_fetch_or(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2073 return p->fetch_or( val );
2076 static inline T atomic_fetch_or(atomic<T>* p, T val) CDS_NOEXCEPT
2078 return p->fetch_or( val );
2082 static inline T atomic_fetch_or_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2084 return p->fetch_or( val, order );
2087 static inline T atomic_fetch_or_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2089 return p->fetch_or( val, order );
2093 static inline T atomic_fetch_xor(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2095 return p->fetch_xor( val );
2098 static inline T atomic_fetch_xor(atomic<T>* p, T val) CDS_NOEXCEPT
2100 return p->fetch_xor( val );
2104 static inline T atomic_fetch_xor_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2106 return p->fetch_xor( val, order );
2109 static inline T atomic_fetch_xor_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2111 return p->fetch_xor( val, order );
2115 typedef struct atomic_flag
2117 void clear( memory_order order = memory_order_seq_cst ) volatile CDS_NOEXCEPT
2119 assert( order != memory_order_acquire
2120 && order != memory_order_acq_rel
2121 && order != memory_order_consume
2123 platform::atomic_flag_clear( &m_Flag, order );
2125 void clear( memory_order order = memory_order_seq_cst ) CDS_NOEXCEPT
2127 assert( order != memory_order_acquire
2128 && order != memory_order_acq_rel
2129 && order != memory_order_consume
2131 platform::atomic_flag_clear( &m_Flag, order );
2134 bool test_and_set( memory_order order = memory_order_seq_cst ) volatile CDS_NOEXCEPT
2136 return platform::atomic_flag_tas( &m_Flag, order );
2138 bool test_and_set( memory_order order = memory_order_seq_cst ) CDS_NOEXCEPT
2140 return platform::atomic_flag_tas( &m_Flag, order );
2143 atomic_flag() = default;
2145 atomic_flag(const atomic_flag&) = delete;
2146 atomic_flag& operator=(const atomic_flag&) = delete;
2147 atomic_flag& operator=(const atomic_flag&) volatile = delete;
2149 platform::atomic_flag_type volatile m_Flag;
2152 static inline bool atomic_flag_test_and_set(volatile atomic_flag* p) CDS_NOEXCEPT
2154 return p->test_and_set();
2156 static inline bool atomic_flag_test_and_set(atomic_flag * p) CDS_NOEXCEPT
2158 return p->test_and_set();
2160 static inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag* p, memory_order order) CDS_NOEXCEPT
2162 return p->test_and_set( order );
2164 static inline bool atomic_flag_test_and_set_explicit(atomic_flag* p, memory_order order) CDS_NOEXCEPT
2166 return p->test_and_set( order );
2168 static inline void atomic_flag_clear(volatile atomic_flag* p) CDS_NOEXCEPT
2172 static inline void atomic_flag_clear(atomic_flag* p) CDS_NOEXCEPT
2176 static inline void atomic_flag_clear_explicit(volatile atomic_flag* p, memory_order order) CDS_NOEXCEPT
2178 return p->clear( order );
2180 static inline void atomic_flag_clear_explicit(atomic_flag* p, memory_order order) CDS_NOEXCEPT
2182 return p->clear( order );
2186 static inline void atomic_thread_fence(memory_order order) CDS_NOEXCEPT
2188 platform::thread_fence( order );
2189 CDS_COMPILER_RW_BARRIER;
2191 static inline void atomic_signal_fence(memory_order order) CDS_NOEXCEPT
2193 platform::signal_fence( order );
2196 }} // namespace cds::cxx11_atomic
2199 #endif // #ifndef __CDS_COMPILER_CXX11_ATOMIC_H