10 #define MI_BASE_ATOM_H
16 #if defined( MI_ARCH_X86) && (defined( MI_COMPILER_GCC) || defined( MI_COMPILER_ICC))
17 # define MI_ATOM32_X86GCC
18 #elif (__cplusplus >= 201103L)
19 # define MI_ATOM32_STD
21 #elif defined( MI_ARCH_X86) && defined( MI_COMPILER_MSC)
22 # define MI_ATOM32_X86MSC
24 # pragma intrinsic( _InterlockedExchangeAdd)
25 # pragma intrinsic( _InterlockedCompareExchange)
27 # define MI_ATOM32_GENERIC
49 #if defined( MI_ATOM32_STD) || defined( MI_ATOM32_GENERIC)
79 operator Uint32()
const {
return m_value; }
85 #if defined( MI_ATOM32_STD)
87 std::atomic_uint32_t m_value;
93 #if defined( MI_ATOM32_GENERIC)
99 #if !defined( MI_FOR_DOXYGEN_ONLY)
101 #if defined( MI_ATOM32_X86GCC)
108 "lock; xaddl %0,%1\n"
110 :
"=&r"( retval),
"+m"( m_value)
123 "lock; xaddl %0,%1\n"
125 :
"=&r"( retval),
"+m"( m_value)
137 "lock; xaddl %0,%1\n"
139 :
"=&r"( retval),
"+m"( m_value)
151 "lock; xaddl %0,%1\n"
152 :
"=&r"( retval),
"+m"( m_value)
164 "lock; xaddl %0,%1\n"
166 :
"=&r"( retval),
"+m"( m_value)
178 "lock; xaddl %0,%1\n"
179 :
"=&r"( retval),
"+m"( m_value)
192 "lock; cmpxchg %2,%1\n"
194 :
"=&a"( retval),
"+m"( m_value)
201 #elif defined( MI_ATOM32_STD)
203 inline Atom32::Atom32(
const Atom32& other) : m_value( other.m_value.load()) { }
207 m_value = rhs.m_value.load();
245 return m_value.exchange( rhs);
248 #elif defined( MI_ATOM32_X86MSC)
252 return _InterlockedExchangeAdd( reinterpret_cast<volatile long*>( &m_value), rhs) + rhs;
257 return _InterlockedExchangeAdd(
258 reinterpret_cast<volatile long*>( &m_value), -static_cast<const Sint32>( rhs)) - rhs;
263 return _InterlockedExchangeAdd( reinterpret_cast<volatile long*>( &m_value), 1L) + 1L;
268 return _InterlockedExchangeAdd( reinterpret_cast<volatile long*>( &m_value), 1L);
273 return _InterlockedExchangeAdd( reinterpret_cast<volatile long*>( &m_value), -1L) - 1L;
278 return _InterlockedExchangeAdd( reinterpret_cast<volatile long*>( &m_value), -1L);
283 return _InterlockedExchange( reinterpret_cast<volatile long*>( &m_value), rhs);
286 #elif defined( MI_ATOM32_GENERIC)
288 inline Atom32::Atom32(
const Atom32& other) : m_value( other.m_value) { }
292 m_value = rhs.m_value;
299 return m_value += rhs;
305 return m_value -= rhs;
341 #error One of MI_ATOM32_X86GCC, MI_ATOM32_STD, MI_ATOM32_X86MSC, or MI_ATOM32_GENERIC must be \
345 #undef MI_ATOM32_X86GCC
347 #undef MI_ATOM32_X86MSC
348 #undef MI_ATOM32_GENERIC
350 #endif // !MI_FOR_DOXYGEN_ONLY
358 #endif // MI_BASE_ATOM_H