3 #ifndef __CDS_COMPILER_GCC_X86_CXX11_ATOMIC_H
4 #define __CDS_COMPILER_GCC_X86_CXX11_ATOMIC_H
7 #include <cds/compiler/gcc/x86/cxx11_atomic32.h>
10 namespace cds { namespace cxx11_atomic {
11 namespace platform { CDS_CXX11_INLINE_NAMESPACE namespace gcc { CDS_CXX11_INLINE_NAMESPACE namespace x86 {
13 //-----------------------------------------------------------------------------
15 //-----------------------------------------------------------------------------
18 static inline bool cas64_strong( T volatile * pDest, T& expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
20 static_assert( sizeof(T) == 8, "Illegal size of operand" );
21 assert( cds::details::is_aligned( pDest, 8 ));
26 fence_before(mo_success);
28 // We must save EBX in PIC mode
29 __asm__ __volatile__ (
30 "movl %%ebx, %[ebxStore]\n"
31 "movl %[desiredLo], %%ebx\n"
32 "lock; cmpxchg8b 0(%[pDest])\n"
33 "movl %[ebxStore], %%ebx\n"
34 : [prev] "=A" (prev), [ebxStore] "=m" (ebxStore)
35 : [desiredLo] "D" ((int)desired), [desiredHi] "c" ((int)(desired >> 32)), [pDest] "S" (pDest), "0" (prev)
37 bool success = (prev == expected);
39 fence_after(mo_success);
48 static inline bool cas64_weak( T volatile * pDest, T& expected, T desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
50 return cas64_strong( pDest, expected, desired, mo_success, mo_fail );
54 static inline T load64( T volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
56 static_assert( sizeof(T) == 8, "Illegal size of operand" );
57 assert( order == memory_order_relaxed
58 || order == memory_order_consume
59 || order == memory_order_acquire
60 || order == memory_order_seq_cst
63 assert( cds::details::is_aligned( pSrc, 8 ));
65 T CDS_DATA_ALIGNMENT(8) v;
67 "movq (%[pSrc]), %[v] ; \n\t"
77 static inline T exchange64( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
79 static_assert( sizeof(T) == 8, "Illegal size of operand" );
80 assert( cds::details::is_aligned( pDest, 8 ));
82 T cur = load64( pDest, memory_order_relaxed );
84 } while (!cas64_weak( pDest, cur, v, order, memory_order_relaxed ));
89 static inline void store64( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
91 static_assert( sizeof(T) == 8, "Illegal size of operand" );
92 assert( order == memory_order_relaxed
93 || order == memory_order_release
94 || order == memory_order_seq_cst
97 assert( cds::details::is_aligned( pDest, 8 ));
99 if ( order != memory_order_seq_cst ) {
100 fence_before( order );
101 // Atomically stores 64bit value by SSE instruction
102 __asm__ __volatile__(
103 "movq %[val], (%[pDest]) ; \n\t"
105 : [val] "x" (val), [pDest] "r" (pDest)
110 exchange64( pDest, val, order );
115 //-----------------------------------------------------------------------------
116 // pointer primitives
117 //-----------------------------------------------------------------------------
119 template <typename T>
120 static inline T * exchange_ptr( T * volatile * pDest, T * v, memory_order order ) CDS_NOEXCEPT
122 static_assert( sizeof(T *) == sizeof(void *), "Illegal size of operand" );
124 return (T *) exchange32( (uint32_t volatile *) pDest, (uint32_t) v, order );
127 template <typename T>
128 static inline void store_ptr( T * volatile * pDest, T * src, memory_order order ) CDS_NOEXCEPT
130 static_assert( sizeof(T *) == sizeof(void *), "Illegal size of operand" );
131 assert( order == memory_order_relaxed
132 || order == memory_order_release
133 || order == memory_order_seq_cst
137 if ( order != memory_order_seq_cst ) {
138 fence_before( order );
142 exchange_ptr( pDest, src, order );
146 template <typename T>
147 static inline T * load_ptr( T * volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
149 static_assert( sizeof(T *) == sizeof(void *), "Illegal size of operand" );
150 assert( order == memory_order_relaxed
151 || order == memory_order_consume
152 || order == memory_order_acquire
153 || order == memory_order_seq_cst
158 fence_after_load( order );
162 template <typename T>
163 static inline bool cas_ptr_strong( T * volatile * pDest, T *& expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
165 static_assert( sizeof(T *) == sizeof(void *), "Illegal size of operand" );
167 return cas32_strong( (uint32_t volatile *) pDest, *reinterpret_cast<uint32_t *>( &expected ), (uint32_t) desired, mo_success, mo_fail );
170 template <typename T>
171 static inline bool cas_ptr_weak( T * volatile * pDest, T *& expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
173 return cas_ptr_strong( pDest, expected, desired, mo_success, mo_fail );
175 }} // namespace gcc::x86
177 #ifndef CDS_CXX11_INLINE_NAMESPACE_SUPPORT
178 using namespace gcc::x86;
180 } // namespace platform
181 }} // namespace cds::cxx11_atomic
184 #endif // #ifndef __CDS_COMPILER_GCC_X86_CXX11_ATOMIC_H