diff options
author | Jose <jose@zeroc.com> | 2015-02-18 19:23:23 +0100 |
---|---|---|
committer | Jose <jose@zeroc.com> | 2015-02-18 19:23:23 +0100 |
commit | 7e570d78415b644cc4a4f7ed62029491609cbb1d (patch) | |
tree | 283fc9aec652376edbdf369d08844f9ae3a6824f /cpp/src | |
parent | - Add IceLocatorDiscovery to the ruby and python extensions. (diff) | |
download | ice-7e570d78415b644cc4a4f7ed62029491609cbb1d.tar.bz2 ice-7e570d78415b644cc4a4f7ed62029491609cbb1d.tar.xz ice-7e570d78415b644cc4a4f7ed62029491609cbb1d.zip |
Fixed (ICE-6317) - Use std::atomic for C++11 builds
Diffstat (limited to 'cpp/src')
-rw-r--r-- | cpp/src/IceUtil/Shared.cpp | 102 |
1 files changed, 15 insertions, 87 deletions
diff --git a/cpp/src/IceUtil/Shared.cpp b/cpp/src/IceUtil/Shared.cpp index 1b84f7e5dc9..f242ee8d986 100644 --- a/cpp/src/IceUtil/Shared.cpp +++ b/cpp/src/IceUtil/Shared.cpp @@ -11,78 +11,6 @@ using namespace IceUtil; -#ifdef ICE_HAS_ATOMIC_FUNCTIONS - -namespace IceUtilInternal -{ - -// -// Linux only. Unfortunately, asm/atomic.h builds non-SMP safe code -// with non-SMP kernels. This means that executables compiled with a -// non-SMP kernel would fail randomly due to concurrency errors with -// reference counting on SMP hosts. Therefore the relevent pieces of -// atomic.h are more-or-less duplicated. -// - -/* - * atomicInc - increment ice_atomic variable - * @v: pointer of type AtomicCounter - * - * Atomically increments @v by 1. Note that the guaranteed useful - * range of an AtomicCounter is only 24 bits. - * - * Inlined because this operation is performance critical. - */ -static inline void atomicInc(volatile int* counter) -{ - __asm__ __volatile__( - "lock ; incl %0" - :"=m" (*counter) - :"m" (*counter)); -} - -/** - * atomicDecAndTest - decrement and test - * @v: pointer of type AtomicCounter - * - * Atomically decrements @v by 1 and returns true if the result is 0, - * or false for all other cases. Note that the guaranteed useful - * range of an AtomicCounter is only 24 bits. - * - * Inlined because this operation is performance critical. - */ -static inline int atomicDecAndTest(volatile int* counter) -{ - unsigned char c; - __asm__ __volatile__( - "lock ; decl %0; sete %1" - :"=m" (*counter), "=qm" (c) - :"m" (*counter) : "memory"); - return c != 0; -} - -/** - * atomicExchangeAdd - same as InterlockedExchangeAdd. This - * didn't come from atomic.h (the code was derived from similar code - * in /usr/include/asm/rwsem.h) - * - * Inlined because this operation is performance critical. - */ -static inline int atomicExchangeAdd(volatile int* counter, int i) -{ - int tmp = i; - __asm__ __volatile__( - "lock ; xadd %0,(%2)" - :"+r"(tmp), "=m"(*counter) - :"r"(counter), "m"(*counter) - : "memory"); - return tmp + i; -} - -} - -#endif - // // Flag constant used by the Shared class. Derived classes // such as GCObject define more flag constants. @@ -116,7 +44,10 @@ IceUtil::Shared::Shared(const Shared&) : void IceUtil::Shared::__incRef() { -#if defined(_WIN32) +#if defined(ICE_CPP11) + assert(_ref.fetch_add(0, std::memory_order_relaxed) >= 0); + ++_ref; +#elif defined(_WIN32) assert(InterlockedExchangeAdd(&_ref, 0) >= 0); InterlockedIncrement(&_ref); #elif defined(ICE_HAS_GCC_BUILTINS) @@ -126,9 +57,6 @@ IceUtil::Shared::__incRef() # endif __sync_fetch_and_add(&_ref, 1); assert(c >= 0); -#elif defined(ICE_HAS_ATOMIC_FUNCTIONS) - assert(IceUtilInternal::atomicExchangeAdd(&_ref, 0) >= 0); - IceUtilInternal::atomicInc(&_ref); #else _mutex.lock(); assert(_ref >= 0); @@ -140,7 +68,13 @@ IceUtil::Shared::__incRef() void IceUtil::Shared::__decRef() { -#if defined(_WIN32) +#if defined(ICE_CPP11) + assert(_ref.fetch_add(0, std::memory_order_relaxed) > 0); + if(--_ref == 0 && !(_flags & NoDelete)) + { + delete this; + } +#elif defined(_WIN32) assert(InterlockedExchangeAdd(&_ref, 0) > 0); if(InterlockedDecrement(&_ref) == 0 && !(_flags & NoDelete)) { @@ -153,15 +87,9 @@ IceUtil::Shared::__decRef() { delete this; } -#elif defined(ICE_HAS_ATOMIC_FUNCTIONS) - assert(IceUtilInternal::atomicExchangeAdd(&_ref, 0) > 0); - if(IceUtilInternal::atomicDecAndTest(&_ref) && !(_flags & NoDelete)) - { - delete this; - } #else - _mutex.lock(); bool doDelete = false; + _mutex.lock(); assert(_ref > 0); if(--_ref == 0) { @@ -179,12 +107,12 @@ IceUtil::Shared::__decRef() int IceUtil::Shared::__getRef() const { -#if defined(_WIN32) +#if defined(ICE_CPP11) + return _ref.load(std::memory_order_relaxed); +#elif defined(_WIN32) return InterlockedExchangeAdd(const_cast<LONG*>(&_ref), 0); #elif defined(ICE_HAS_GCC_BUILTINS) return __sync_fetch_and_sub(const_cast<volatile int*>(&_ref), 0); -#elif defined(ICE_HAS_ATOMIC_FUNCTIONS) - return IceUtilInternal::atomicExchangeAdd(const_cast<volatile int*>(&_ref), 0); #else _mutex.lock(); int ref = _ref; |