3 #ifndef __ZMQ_ATOMIC_PTR_HPP_INCLUDED__
4 #define __ZMQ_ATOMIC_PTR_HPP_INCLUDED__
8 #if defined ZMQ_FORCE_MUTEXES
9 #define ZMQ_ATOMIC_PTR_MUTEX
10 #elif (defined __cplusplus && __cplusplus >= 201103L) \
11 || (defined _MSC_VER && _MSC_VER >= 1900)
12 #define ZMQ_ATOMIC_PTR_CXX11
13 #elif defined ZMQ_HAVE_ATOMIC_INTRINSICS
14 #define ZMQ_ATOMIC_PTR_INTRINSIC
15 #elif (defined __i386__ || defined __x86_64__) && defined __GNUC__
16 #define ZMQ_ATOMIC_PTR_X86
17 #elif defined __ARM_ARCH_7A__ && defined __GNUC__
18 #define ZMQ_ATOMIC_PTR_ARM
19 #elif defined __tile__
20 #define ZMQ_ATOMIC_PTR_TILE
21 #elif defined ZMQ_HAVE_WINDOWS
22 #define ZMQ_ATOMIC_PTR_WINDOWS
23 #elif (defined ZMQ_HAVE_SOLARIS || defined ZMQ_HAVE_NETBSD \
24 || defined ZMQ_HAVE_GNU)
25 #define ZMQ_ATOMIC_PTR_ATOMIC_H
27 #define ZMQ_ATOMIC_PTR_MUTEX
30 #if defined ZMQ_ATOMIC_PTR_MUTEX
32 #elif defined ZMQ_ATOMIC_PTR_CXX11
34 #elif defined ZMQ_ATOMIC_PTR_WINDOWS
36 #elif defined ZMQ_ATOMIC_PTR_ATOMIC_H
38 #elif defined ZMQ_ATOMIC_PTR_TILE
39 #include <arch/atomic.h>
44 #if !defined ZMQ_ATOMIC_PTR_CXX11
53 #if defined ZMQ_ATOMIC_PTR_WINDOWS
54 return InterlockedExchangePointer ((PVOID *) ptr_,
val_);
55 #elif defined ZMQ_ATOMIC_PTR_INTRINSIC
56 return __atomic_exchange_n (ptr_,
val_, __ATOMIC_ACQ_REL);
57 #elif defined ZMQ_ATOMIC_PTR_ATOMIC_H
58 return atomic_swap_ptr (ptr_,
val_);
59 #elif defined ZMQ_ATOMIC_PTR_TILE
60 return arch_atomic_exchange (ptr_,
val_);
61 #elif defined ZMQ_ATOMIC_PTR_X86
63 __asm__
volatile(
"lock; xchg %0, %2"
64 :
"=r"(old),
"=m"(*ptr_)
65 :
"m"(*ptr_),
"0"(
val_));
67 #elif defined ZMQ_ATOMIC_PTR_ARM
70 __asm__
volatile(
" dmb sy\n\t"
71 "1: ldrex %1, [%3]\n\t"
72 " strex %0, %4, [%3]\n\t"
76 :
"=&r"(flag),
"=&r"(old),
"+Qo"(*ptr_)
77 :
"r"(ptr_),
"r"(
val_)
80 #elif defined ZMQ_ATOMIC_PTR_MUTEX
87 #error atomic_ptr is not implemented for this platform
100 #if defined ZMQ_ATOMIC_PTR_WINDOWS
101 return InterlockedCompareExchangePointer ((
volatile PVOID *) ptr_,
val_,
103 #elif defined ZMQ_ATOMIC_PTR_INTRINSIC
105 __atomic_compare_exchange_n (ptr_, &old,
val_,
false, __ATOMIC_RELEASE,
108 #elif defined ZMQ_ATOMIC_PTR_ATOMIC_H
109 return atomic_cas_ptr (ptr_, cmp_,
val_);
110 #elif defined ZMQ_ATOMIC_PTR_TILE
111 return arch_atomic_val_compare_and_exchange (ptr_, cmp_,
val_);
112 #elif defined ZMQ_ATOMIC_PTR_X86
114 __asm__
volatile(
"lock; cmpxchg %2, %3"
115 :
"=a"(old),
"=m"(*ptr_)
116 :
"r"(
val_),
"m"(*ptr_),
"0"(cmp_)
119 #elif defined ZMQ_ATOMIC_PTR_ARM
122 __asm__
volatile(
" dmb sy\n\t"
123 "1: ldrex %1, [%3]\n\t"
127 " strexeq %0, %5, [%3]\n\t"
131 :
"=&r"(flag),
"=&r"(old),
"+Qo"(*ptr_)
132 :
"r"(ptr_),
"r"(cmp_),
"r"(
val_)
135 #elif defined ZMQ_ATOMIC_PTR_MUTEX
143 #error atomic_ptr is not implemented for this platform
165 #if defined ZMQ_ATOMIC_PTR_CXX11
166 return _ptr.exchange (
val_, std::memory_order_acq_rel);
183 #if defined ZMQ_ATOMIC_PTR_CXX11
184 _ptr.compare_exchange_strong (cmp_,
val_, std::memory_order_acq_rel);
197 #if defined ZMQ_ATOMIC_PTR_CXX11
198 std::atomic<T *>
_ptr;
203 #if defined ZMQ_ATOMIC_PTR_MUTEX
207 #if !defined ZMQ_ATOMIC_PTR_CXX11
223 #if defined ZMQ_ATOMIC_PTR_CXX11
237 #if defined ZMQ_ATOMIC_PTR_CXX11
238 return _value.load (std::memory_order_acquire);
241 #if defined ZMQ_ATOMIC_PTR_MUTEX
243 #if defined __SUNPRO_CC
254 #if defined ZMQ_ATOMIC_PTR_CXX11
260 #if defined ZMQ_ATOMIC_PTR_MUTEX
270 #undef ZMQ_ATOMIC_PTR_MUTEX
271 #undef ZMQ_ATOMIC_PTR_INTRINSIC
272 #undef ZMQ_ATOMIC_PTR_CXX11
273 #undef ZMQ_ATOMIC_PTR_X86
274 #undef ZMQ_ATOMIC_PTR_ARM
275 #undef ZMQ_ATOMIC_PTR_TILE
276 #undef ZMQ_ATOMIC_PTR_WINDOWS
277 #undef ZMQ_ATOMIC_PTR_ATOMIC_H