3 #ifndef CDSLIB_COMPILER_GCC_X86_CXX11_ATOMIC_H
4 #define CDSLIB_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 ));
66 T CDS_DATA_ALIGNMENT(8) v;
68 "movq (%[pSrc]), %[v] ; \n\t"
78 static inline T exchange64( T volatile * pDest, T v, memory_order order ) CDS_NOEXCEPT
80 static_assert( sizeof(T) == 8, "Illegal size of operand" );
81 assert( cds::details::is_aligned( pDest, 8 ));
83 T cur = load64( pDest, memory_order_relaxed );
85 } while (!cas64_weak( pDest, cur, v, order, memory_order_relaxed ));
90 static inline void store64( T volatile * pDest, T val, memory_order order ) CDS_NOEXCEPT
92 static_assert( sizeof(T) == 8, "Illegal size of operand" );
93 assert( order == memory_order_relaxed
94 || order == memory_order_release
95 || order == memory_order_seq_cst
98 assert( cds::details::is_aligned( pDest, 8 ));
100 if ( order != memory_order_seq_cst ) {
101 fence_before( order );
102 // Atomically stores 64bit value by SSE instruction
103 __asm__ __volatile__(
104 "movq %[val], (%[pDest]) ; \n\t"
106 : [val] "x" (val), [pDest] "r" (pDest)
111 exchange64( pDest, val, order );
116 //-----------------------------------------------------------------------------
117 // pointer primitives
118 //-----------------------------------------------------------------------------
120 template <typename T>
121 static inline T * exchange_ptr( T * volatile * pDest, T * v, memory_order order ) CDS_NOEXCEPT
123 static_assert( sizeof(T *) == sizeof(void *), "Illegal size of operand" );
125 return (T *) exchange32( (uint32_t volatile *) pDest, (uint32_t) v, order );
128 template <typename T>
129 static inline void store_ptr( T * volatile * pDest, T * src, memory_order order ) CDS_NOEXCEPT
131 static_assert( sizeof(T *) == sizeof(void *), "Illegal size of operand" );
132 assert( order == memory_order_relaxed
133 || order == memory_order_release
134 || order == memory_order_seq_cst
138 if ( order != memory_order_seq_cst ) {
139 fence_before( order );
143 exchange_ptr( pDest, src, order );
147 template <typename T>
148 static inline T * load_ptr( T * volatile const * pSrc, memory_order order ) CDS_NOEXCEPT
150 static_assert( sizeof(T *) == sizeof(void *), "Illegal size of operand" );
151 assert( order == memory_order_relaxed
152 || order == memory_order_consume
153 || order == memory_order_acquire
154 || order == memory_order_seq_cst
159 fence_after_load( order );
163 template <typename T>
164 static inline bool cas_ptr_strong( T * volatile * pDest, T *& expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
166 static_assert( sizeof(T *) == sizeof(void *), "Illegal size of operand" );
168 return cas32_strong( (uint32_t volatile *) pDest, *reinterpret_cast<uint32_t *>( &expected ), (uint32_t) desired, mo_success, mo_fail );
171 template <typename T>
172 static inline bool cas_ptr_weak( T * volatile * pDest, T *& expected, T * desired, memory_order mo_success, memory_order mo_fail ) CDS_NOEXCEPT
174 return cas_ptr_strong( pDest, expected, desired, mo_success, mo_fail );
176 }} // namespace gcc::x86
178 #ifndef CDS_CXX11_INLINE_NAMESPACE_SUPPORT
179 using namespace gcc::x86;
181 } // namespace platform
182 }} // namespace cds::cxx11_atomic
185 #endif // #ifndef CDSLIB_COMPILER_GCC_X86_CXX11_ATOMIC_H