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_atomics {
11 typedef enum memory_order {
20 }} // namespace cds::cxx11_atomics
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_atomics {
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
256 assert( expected != NULL );
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
261 assert( expected != NULL );
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
274 assert( expected != NULL );
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
279 assert( expected != NULL );
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
478 assert( expected != NULL );
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
483 assert( expected != NULL );
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
496 assert( expected != NULL );
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
501 assert( expected != NULL );
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
700 assert( expected != NULL );
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
705 assert( expected != NULL );
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
718 assert( expected != NULL );
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
723 assert( expected != NULL );
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
922 assert( expected != NULL );
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
927 assert( expected != NULL );
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
940 assert( expected != NULL );
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
945 assert( expected != NULL );
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
1144 assert( expected != NULL );
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
1149 assert( expected != NULL );
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
1162 assert( expected != NULL );
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
1167 assert( expected != NULL );
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 # ifdef CDS_CXX11_EXPLICITLY_DEFAULTED_FUNCTION_SUPPORT
1288 atomic_noncopyable() = default;
1290 atomic_noncopyable()
1296 template <typename T>
1297 struct atomic_integral
1298 #ifndef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1299 : atomic_noncopyable
1303 typename cds::details::aligned_type<T, sizeof(T)>::type volatile m_val;
1305 typedef atomic_integral_ops<T, sizeof(T)> atomic_ops;
1307 typedef T atomic_type;
1309 bool is_lock_free() const volatile CDS_NOEXCEPT
1313 bool is_lock_free() const CDS_NOEXCEPT
1317 void store(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1319 atomic_ops::atomic_store_explicit( &m_val, val, order );
1321 void store(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1323 atomic_ops::atomic_store_explicit( &m_val, val, order );
1326 T load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1328 return atomic_ops::atomic_load_explicit( &m_val, order );
1330 T load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1332 return atomic_ops::atomic_load_explicit( &m_val, order );
1335 operator T() const volatile CDS_NOEXCEPT
1339 operator T() const CDS_NOEXCEPT
1344 T exchange(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1346 return atomic_ops::atomic_exchange_explicit( &m_val, val, order );
1348 T exchange(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1350 return atomic_ops::atomic_exchange_explicit( &m_val, val, order );
1353 bool compare_exchange_weak(T& expected, T desired , memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1355 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_val, &expected, desired, success_order, failure_order );
1357 bool compare_exchange_weak(T& expected, T desired , memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1359 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_val, &expected, desired, success_order, failure_order );
1361 bool compare_exchange_strong(T& expected, T desired , memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1363 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_val, &expected, desired, success_order, failure_order );
1365 bool compare_exchange_strong(T& expected, T desired , memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1367 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_val, &expected, desired, success_order, failure_order );
1369 bool compare_exchange_weak(T& expected, T desired , memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1371 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1373 bool compare_exchange_weak(T& expected, T desired , memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1375 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1377 bool compare_exchange_strong(T& expected, T desired , memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1379 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1381 bool compare_exchange_strong(T& expected, T desired , memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1383 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1386 T fetch_add(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1388 return atomic_ops::atomic_fetch_add_explicit( &m_val, val, order );
1390 T fetch_add(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1392 return atomic_ops::atomic_fetch_add_explicit( &m_val, val, order );
1394 T fetch_sub(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1396 return atomic_ops::atomic_fetch_sub_explicit( &m_val, val, order );
1398 T fetch_sub(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1400 return atomic_ops::atomic_fetch_sub_explicit( &m_val, val, order );
1402 T fetch_and(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1404 return atomic_ops::atomic_fetch_and_explicit( &m_val, val, order );
1406 T fetch_and(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1408 return atomic_ops::atomic_fetch_and_explicit( &m_val, val, order );
1411 T fetch_or(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1413 return atomic_ops::atomic_fetch_or_explicit( &m_val, val, order );
1415 T fetch_or(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1417 return atomic_ops::atomic_fetch_or_explicit( &m_val, val, order );
1419 T fetch_xor(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1421 return atomic_ops::atomic_fetch_xor_explicit( &m_val, val, order );
1423 T fetch_xor(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1425 return atomic_ops::atomic_fetch_xor_explicit( &m_val, val, order );
1428 #ifdef CDS_CXX11_EXPLICITLY_DEFAULTED_FUNCTION_SUPPORT
1429 atomic_integral() = default;
1431 atomic_integral() CDS_NOEXCEPT
1434 CDS_CONSTEXPR atomic_integral(T val) CDS_NOEXCEPT
1438 #ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1439 atomic_integral(const atomic_integral&) = delete;
1440 atomic_integral& operator=(const atomic_integral&) = delete;
1441 atomic_integral& operator=(const atomic_integral&) volatile = delete;
1443 T operator=(T val) volatile CDS_NOEXCEPT
1448 T operator=(T val) CDS_NOEXCEPT
1455 T operator++(int) volatile CDS_NOEXCEPT
1457 return fetch_add( 1 );
1459 T operator++(int) CDS_NOEXCEPT
1461 return fetch_add( 1 );
1463 T operator--(int) volatile CDS_NOEXCEPT
1465 return fetch_sub( 1 );
1467 T operator--(int) CDS_NOEXCEPT
1469 return fetch_sub( 1 );
1473 T operator++() volatile CDS_NOEXCEPT
1475 return fetch_add( 1 ) + 1;
1477 T operator++() CDS_NOEXCEPT
1479 return fetch_add( 1 ) + 1;
1481 T operator--() volatile CDS_NOEXCEPT
1483 return fetch_sub( 1 ) - 1;
1485 T operator--() CDS_NOEXCEPT
1487 return fetch_sub( 1 ) - 1;
1491 T operator+=(T val) volatile CDS_NOEXCEPT
1493 return fetch_add( val ) + val;
1495 T operator+=(T val) CDS_NOEXCEPT
1497 return fetch_add( val ) + val;
1499 T operator-=(T val) volatile CDS_NOEXCEPT
1501 return fetch_sub( val ) - val;
1503 T operator-=(T val) CDS_NOEXCEPT
1505 return fetch_sub( val ) - val;
1507 T operator&=(T val) volatile CDS_NOEXCEPT
1509 return fetch_and( val ) & val;
1511 T operator&=(T val) CDS_NOEXCEPT
1513 return fetch_and( val ) & val;
1515 T operator|=(T val) volatile CDS_NOEXCEPT
1517 return fetch_or( val ) | val;
1519 T operator|=(T val) CDS_NOEXCEPT
1521 return fetch_or( val ) | val;
1523 T operator^=(T val) volatile CDS_NOEXCEPT
1525 return fetch_xor( val ) ^ val;
1527 T operator^=(T val) CDS_NOEXCEPT
1529 return fetch_xor( val ) ^ val;
1533 template <typename Type>
1534 struct select_primary_type {
1535 typedef typename details::primary_type<sizeof(Type)>::type type;
1538 struct select_primary_type<bool> {
1542 } // namespace details
1546 #ifndef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1547 : details::atomic_noncopyable
1551 typedef details::atomic_generic_ops<T, sizeof(T), typename details::select_primary_type<T>::type > atomic_ops;
1555 bool is_lock_free() const volatile CDS_NOEXCEPT
1559 bool is_lock_free() const CDS_NOEXCEPT
1564 void store(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1566 atomic_ops::atomic_store_explicit( &m_data, val, order );
1568 void store(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1570 atomic_ops::atomic_store_explicit( &m_data, val, order );
1573 T load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1575 return atomic_ops::atomic_load_explicit( &m_data, order );
1577 T load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1579 return atomic_ops::atomic_load_explicit( &m_data, order );
1582 operator T() const volatile CDS_NOEXCEPT
1586 operator T() const CDS_NOEXCEPT
1591 T exchange(T val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1593 return atomic_ops::atomic_exchange_explicit( &m_data, val, order );
1595 T exchange(T val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1597 return atomic_ops::atomic_exchange_explicit( &m_data, val, order );
1600 bool compare_exchange_weak(T& expected, T desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1602 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_data, &expected, desired, success_order, failure_order );
1604 bool compare_exchange_weak(T& expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1606 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_data, &expected, desired, success_order, failure_order );
1608 bool compare_exchange_strong(T& expected, T desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1610 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_data, &expected, desired, success_order, failure_order );
1612 bool compare_exchange_strong(T& expected, T desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1614 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_data, &expected, desired, success_order, failure_order );
1616 bool compare_exchange_weak(T& expected, T desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1618 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1620 bool compare_exchange_weak(T& expected, T desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1622 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1624 bool compare_exchange_strong(T& expected, T desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1626 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1628 bool compare_exchange_strong(T& expected, T desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1630 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1633 #ifdef CDS_CXX11_EXPLICITLY_DEFAULTED_FUNCTION_SUPPORT
1639 CDS_CONSTEXPR atomic(T val)
1643 #ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1644 atomic(const atomic&) = delete;
1645 atomic& operator=(const atomic&) = delete;
1646 atomic& operator=(const atomic&) volatile = delete;
1649 T operator=(T val) volatile CDS_NOEXCEPT
1654 T operator=(T val) CDS_NOEXCEPT
1661 #if defined(CDS_CXX11_EXPLICITLY_DEFAULTED_FUNCTION_SUPPORT) && defined(CDS_CXX11_DELETE_DEFINITION_SUPPORT)
1662 # define CDS_DECLARE_ATOMIC_INTEGRAL( _type ) \
1664 struct atomic<_type>: public details::atomic_integral<_type> \
1667 typedef details::atomic_integral<_type> base_class ; \
1669 atomic() = default; \
1670 atomic(_type val) CDS_NOEXCEPT : base_class(val) {} \
1671 atomic(const atomic&) = delete; \
1672 atomic& operator=(const atomic&) = delete; \
1673 atomic& operator=(const atomic&) volatile = delete; \
1674 _type operator=(_type val) volatile CDS_NOEXCEPT { return base_class::operator=(val); } \
1675 _type operator=(_type val) CDS_NOEXCEPT { return base_class::operator=(val); } \
1678 # define CDS_DECLARE_ATOMIC_INTEGRAL( _type ) \
1680 struct atomic<_type>: public details::atomic_integral<_type> \
1683 typedef details::atomic_integral<_type> base_class ; \
1686 atomic(_type val) CDS_NOEXCEPT : base_class(val) {} \
1687 _type operator=(_type val) volatile CDS_NOEXCEPT { return base_class::operator=(val); } \
1688 _type operator=(_type val) CDS_NOEXCEPT { return base_class::operator=(val); } \
1692 CDS_DECLARE_ATOMIC_INTEGRAL(char)
1693 CDS_DECLARE_ATOMIC_INTEGRAL(signed char)
1694 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned char)
1695 CDS_DECLARE_ATOMIC_INTEGRAL(short)
1696 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned short)
1697 CDS_DECLARE_ATOMIC_INTEGRAL(int)
1698 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned int)
1699 CDS_DECLARE_ATOMIC_INTEGRAL(long)
1700 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned long)
1701 CDS_DECLARE_ATOMIC_INTEGRAL(long long)
1702 CDS_DECLARE_ATOMIC_INTEGRAL(unsigned long long)
1703 //#if CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40400
1704 // CDS_DECLARE_ATOMIC_INTEGRAL(char16_t)
1705 // CDS_DECLARE_ATOMIC_INTEGRAL(char32_t)
1707 // CDS_DECLARE_ATOMIC_INTEGRAL(wchar_t)
1709 # undef CDS_DECLARE_ATOMIC_INTEGRAL
1712 template <typename T>
1714 #ifndef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1715 : details::atomic_noncopyable
1720 typedef details::atomic_pointer<T> atomic_ops;
1722 bool is_lock_free() const volatile CDS_NOEXCEPT
1726 bool is_lock_free() const CDS_NOEXCEPT
1731 void store(T * val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1733 atomic_ops::atomic_store_explicit( &m_ptr, val, order );
1735 void store(T * val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1737 atomic_ops::atomic_store_explicit( &m_ptr, val, order );
1740 T * load(memory_order order = memory_order_seq_cst) const volatile CDS_NOEXCEPT
1742 return atomic_ops::atomic_load_explicit( &m_ptr, order );
1744 T * load(memory_order order = memory_order_seq_cst) const CDS_NOEXCEPT
1746 return atomic_ops::atomic_load_explicit( &m_ptr, order );
1749 operator T *() const volatile CDS_NOEXCEPT
1753 operator T *() const CDS_NOEXCEPT
1758 T * exchange(T * val, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1760 return atomic_ops::atomic_exchange_explicit( &m_ptr, val, order );
1762 T * exchange(T * val, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1764 return atomic_ops::atomic_exchange_explicit( &m_ptr, val, order );
1767 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1769 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1771 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1773 return atomic_ops::atomic_compare_exchange_weak_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1775 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order, memory_order failure_order) volatile CDS_NOEXCEPT
1777 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1779 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order, memory_order failure_order) CDS_NOEXCEPT
1781 return atomic_ops::atomic_compare_exchange_strong_explicit( &m_ptr, &expected, desired, success_order, failure_order );
1783 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1785 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1787 bool compare_exchange_weak(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1789 return compare_exchange_weak( expected, desired, success_order, memory_order_relaxed );
1791 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1793 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1795 bool compare_exchange_strong(T *& expected, T * desired, memory_order success_order = memory_order_seq_cst) CDS_NOEXCEPT
1797 return compare_exchange_strong( expected, desired, success_order, memory_order_relaxed );
1800 T * fetch_add(ptrdiff_t offset, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1802 return atomic_ops::atomic_fetch_add_explicit( &m_ptr, offset, order );
1804 T * fetch_add(ptrdiff_t offset, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1806 return atomic_ops::atomic_fetch_add_explicit( &m_ptr, offset, order );
1809 T * fetch_sub(ptrdiff_t offset, memory_order order = memory_order_seq_cst) volatile CDS_NOEXCEPT
1811 return atomic_ops::atomic_fetch_sub_explicit( &m_ptr, offset, order );
1813 T * fetch_sub(ptrdiff_t offset, memory_order order = memory_order_seq_cst) CDS_NOEXCEPT
1815 return atomic_ops::atomic_fetch_sub_explicit( &m_ptr, offset, order );
1818 #ifdef CDS_CXX11_EXPLICITLY_DEFAULTED_FUNCTION_SUPPORT
1821 atomic() CDS_NOEXCEPT
1824 CDS_CONSTEXPR atomic(T * val) CDS_NOEXCEPT
1828 #ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
1829 atomic(const atomic&) = delete;
1830 atomic& operator=(const atomic&) = delete;
1831 atomic& operator=(const atomic&) volatile = delete;
1834 T * operator=(T * val) volatile CDS_NOEXCEPT
1839 T * operator=(T * val) CDS_NOEXCEPT
1847 typedef atomic<bool> atomic_bool;
1848 typedef atomic<char> atomic_char;
1849 typedef atomic<signed char> atomic_schar;
1850 typedef atomic<unsigned char> atomic_uchar;
1851 typedef atomic<short> atomic_short;
1852 typedef atomic<unsigned short> atomic_ushort;
1853 typedef atomic<int> atomic_int;
1854 typedef atomic<unsigned int> atomic_uint;
1855 typedef atomic<long> atomic_long;
1856 typedef atomic<unsigned long> atomic_ulong;
1857 typedef atomic<long long> atomic_llong;
1858 typedef atomic<unsigned long long> atomic_ullong;
1859 #if ( CDS_COMPILER == CDS_COMPILER_GCC && CDS_COMPILER_VERSION >= 40400 ) || CDS_COMPILER == CDS_COMPILER_CLANG
1860 typedef atomic<char16_t> atomic_char16_t;
1861 typedef atomic<char32_t> atomic_char32_t;
1863 typedef atomic<wchar_t> atomic_wchar_t;
1866 typedef atomic<cds::int_least8_t> atomic_int_least8_t;
1867 typedef atomic<cds::uint_least8_t> atomic_uint_least8_t;
1868 typedef atomic<cds::int_least16_t> atomic_int_least16_t;
1869 typedef atomic<cds::uint_least16_t> atomic_uint_least16_t;
1870 typedef atomic<cds::int_least32_t> atomic_int_least32_t;
1871 typedef atomic<cds::uint_least32_t> atomic_uint_least32_t;
1872 typedef atomic<cds::int_least64_t> atomic_int_least64_t;
1873 typedef atomic<cds::uint_least64_t> atomic_uint_least64_t;
1874 typedef atomic<cds::int_fast8_t> atomic_int_fast8_t;
1875 typedef atomic<cds::uint_fast8_t> atomic_uint_fast8_t;
1876 typedef atomic<cds::int_fast16_t> atomic_int_fast16_t;
1877 typedef atomic<cds::uint_fast16_t> atomic_uint_fast16_t;
1878 typedef atomic<cds::int_fast32_t> atomic_int_fast32_t;
1879 typedef atomic<cds::uint_fast32_t> atomic_uint_fast32_t;
1880 typedef atomic<cds::int_fast64_t> atomic_int_fast64_t;
1881 typedef atomic<cds::uint_fast64_t> atomic_uint_fast64_t;
1882 typedef atomic<intptr_t> atomic_intptr_t;
1883 typedef atomic<uintptr_t> atomic_uintptr_t;
1884 typedef atomic<size_t> atomic_size_t;
1885 typedef atomic<ptrdiff_t> atomic_ptrdiff_t;
1886 typedef atomic<cds::intmax_t> atomic_intmax_t;
1887 typedef atomic<cds::uintmax_t> atomic_uintmax_t;
1890 static inline bool atomic_is_lock_free(const volatile atomic<T> * p) CDS_NOEXCEPT
1892 return p->is_lock_free();
1896 static inline bool atomic_is_lock_free(const atomic<T> * p ) CDS_NOEXCEPT
1898 return p->is_lock_free();
1903 static inline void atomic_init(volatile atomic<T> * p, T val) CDS_NOEXCEPT
1909 static inline void atomic_init( atomic<T> * p, T val) CDS_NOEXCEPT
1916 static inline void atomic_store(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1921 static inline void atomic_store(atomic<T>* p, T val) CDS_NOEXCEPT
1927 static inline void atomic_store_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1929 p->store( val, order );
1932 static inline void atomic_store_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1934 p->store( val, order );
1938 static inline T atomic_load(const volatile atomic<T>* p) CDS_NOEXCEPT
1943 static inline T atomic_load(const atomic<T>* p) CDS_NOEXCEPT
1949 static inline T atomic_load_explicit(const volatile atomic<T>* p, memory_order order) CDS_NOEXCEPT
1951 return p->load( order );
1954 static inline T atomic_load_explicit(const atomic<T>* p, memory_order order) CDS_NOEXCEPT
1956 return p->load( order );
1960 static inline T atomic_exchange(volatile atomic<T>* p, T val) CDS_NOEXCEPT
1962 return p->exchange( val );
1965 static inline T atomic_exchange(atomic<T>* p, T val ) CDS_NOEXCEPT
1967 return p->exchange( val );
1971 static inline T atomic_exchange_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1973 return p->exchange( val, order );
1976 static inline T atomic_exchange_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
1978 return p->exchange( val, order );
1982 static inline bool atomic_compare_exchange_weak(volatile atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1984 return p->compare_exchange_weak( *expected, desired );
1987 static inline bool atomic_compare_exchange_weak(atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1989 return p->compare_exchange_weak( *expected, desired );
1993 static inline bool atomic_compare_exchange_strong(volatile atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
1995 return p->compare_exchange_strong( *expected, desired );
1998 static inline bool atomic_compare_exchange_strong(atomic<T>* p, T* expected, T desired) CDS_NOEXCEPT
2000 return p->compare_exchange_strong( *expected, desired );
2004 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
2006 return p->compare_exchange_weak( *expected, desired, success_order, failure_order );
2009 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
2011 return p->compare_exchange_weak( *expected, desired, success_order, failure_order );
2015 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
2017 return p->compare_exchange_strong( *expected, desired, success_order, failure_order );
2020 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
2022 return p->compare_exchange_strong( *expected, desired, success_order, failure_order );
2026 static inline T atomic_fetch_add(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2028 return p->fetch_add( val );
2031 static inline T atomic_fetch_add(atomic<T>* p, T val) CDS_NOEXCEPT
2033 return p->fetch_add( val );
2036 static inline T * atomic_fetch_add(volatile atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2038 return p->fetch_add( offset );
2041 static inline T * atomic_fetch_add(atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2043 return p->fetch_add( offset );
2047 static inline T atomic_fetch_add_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2049 return p->fetch_add( val, order );
2052 static inline T atomic_fetch_add_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2054 return p->fetch_add( val, order );
2057 static inline T * atomic_fetch_add_explicit(volatile atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2059 return p->fetch_add( offset, order );
2062 static inline T * atomic_fetch_add_explicit(atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2064 return p->fetch_add( offset, order );
2068 static inline T atomic_fetch_sub(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2070 return p->fetch_sub( val );
2073 static inline T atomic_fetch_sub(atomic<T>* p, T val) CDS_NOEXCEPT
2075 return p->fetch_sub( val );
2078 static inline T * atomic_fetch_sub(volatile atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2080 return p->fetch_sub( offset );
2083 static inline T * atomic_fetch_sub(atomic<T *>* p, ptrdiff_t offset) CDS_NOEXCEPT
2085 return p->fetch_sub( offset );
2089 static inline T atomic_fetch_sub_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2091 return p->fetch_sub( val, order );
2094 static inline T atomic_fetch_sub_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2096 return p->fetch_sub( val, order );
2099 static inline T * atomic_fetch_sub_explicit(volatile atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2101 return p->fetch_sub( offset, order );
2104 static inline T * atomic_fetch_sub_explicit(atomic<T *>* p, ptrdiff_t offset, memory_order order) CDS_NOEXCEPT
2106 return p->fetch_sub( offset, order );
2110 static inline T atomic_fetch_and(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2112 return p->fetch_and( val );
2115 static inline T atomic_fetch_and(atomic<T>* p, T val) CDS_NOEXCEPT
2117 return p->fetch_and( val );
2121 static inline T atomic_fetch_and_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2123 return p->fetch_and( val, order );
2126 static inline T atomic_fetch_and_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2128 return p->fetch_and( val, order );
2132 static inline T atomic_fetch_or(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2134 return p->fetch_or( val );
2137 static inline T atomic_fetch_or(atomic<T>* p, T val) CDS_NOEXCEPT
2139 return p->fetch_or( val );
2143 static inline T atomic_fetch_or_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2145 return p->fetch_or( val, order );
2148 static inline T atomic_fetch_or_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2150 return p->fetch_or( val, order );
2154 static inline T atomic_fetch_xor(volatile atomic<T>* p, T val) CDS_NOEXCEPT
2156 return p->fetch_xor( val );
2159 static inline T atomic_fetch_xor(atomic<T>* p, T val) CDS_NOEXCEPT
2161 return p->fetch_xor( val );
2165 static inline T atomic_fetch_xor_explicit(volatile atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2167 return p->fetch_xor( val, order );
2170 static inline T atomic_fetch_xor_explicit(atomic<T>* p, T val, memory_order order) CDS_NOEXCEPT
2172 return p->fetch_xor( val, order );
2176 typedef struct atomic_flag
2178 void clear( memory_order order = memory_order_seq_cst ) volatile CDS_NOEXCEPT
2180 assert( order != memory_order_acquire
2181 && order != memory_order_acq_rel
2182 && order != memory_order_consume
2184 platform::atomic_flag_clear( &m_Flag, order );
2186 void clear( memory_order order = memory_order_seq_cst ) CDS_NOEXCEPT
2188 assert( order != memory_order_acquire
2189 && order != memory_order_acq_rel
2190 && order != memory_order_consume
2192 platform::atomic_flag_clear( &m_Flag, order );
2195 bool test_and_set( memory_order order = memory_order_seq_cst ) volatile CDS_NOEXCEPT
2197 return platform::atomic_flag_tas( &m_Flag, order );
2199 bool test_and_set( memory_order order = memory_order_seq_cst ) CDS_NOEXCEPT
2201 return platform::atomic_flag_tas( &m_Flag, order );
2204 #ifdef CDS_CXX11_EXPLICITLY_DEFAULTED_FUNCTION_SUPPORT
2205 atomic_flag() = default;
2206 #elif CDS_COMPILER != CDS_COMPILER_MSVC
2207 // MS VC generate error C2552 "non-aggregates cannot be initialized with initializer list"
2208 // when atomic_flag initializes with ATOMIC_FLAG_INIT
2213 #ifdef CDS_CXX11_DELETE_DEFINITION_SUPPORT
2214 atomic_flag(const atomic_flag&) = delete;
2215 atomic_flag& operator=(const atomic_flag&) = delete;
2216 atomic_flag& operator=(const atomic_flag&) volatile = delete;
2217 #elif CDS_COMPILER != CDS_COMPILER_MSVC
2218 // MS VC generate error C2552 "non-aggregates cannot be initialized with initializer list"
2219 // when atomic_flag initializes with ATOMIC_FLAG_INIT
2221 atomic_flag(const atomic_flag&);
2222 atomic_flag& operator=(const atomic_flag&);
2223 atomic_flag& operator=(const atomic_flag&) volatile;
2227 platform::atomic_flag_type volatile m_Flag;
2230 static inline bool atomic_flag_test_and_set(volatile atomic_flag* p) CDS_NOEXCEPT
2232 return p->test_and_set();
2234 static inline bool atomic_flag_test_and_set(atomic_flag * p) CDS_NOEXCEPT
2236 return p->test_and_set();
2238 static inline bool atomic_flag_test_and_set_explicit(volatile atomic_flag* p, memory_order order) CDS_NOEXCEPT
2240 return p->test_and_set( order );
2242 static inline bool atomic_flag_test_and_set_explicit(atomic_flag* p, memory_order order) CDS_NOEXCEPT
2244 return p->test_and_set( order );
2246 static inline void atomic_flag_clear(volatile atomic_flag* p) CDS_NOEXCEPT
2250 static inline void atomic_flag_clear(atomic_flag* p) CDS_NOEXCEPT
2254 static inline void atomic_flag_clear_explicit(volatile atomic_flag* p, memory_order order) CDS_NOEXCEPT
2256 return p->clear( order );
2258 static inline void atomic_flag_clear_explicit(atomic_flag* p, memory_order order) CDS_NOEXCEPT
2260 return p->clear( order );
2264 static inline void atomic_thread_fence(memory_order order) CDS_NOEXCEPT
2266 platform::thread_fence( order );
2267 CDS_COMPILER_RW_BARRIER;
2269 static inline void atomic_signal_fence(memory_order order) CDS_NOEXCEPT
2271 platform::signal_fence( order );
2274 }} // namespace cds::cxx11_atomics
2277 #endif // #ifndef __CDS_COMPILER_CXX11_ATOMIC_H