summaryrefslogtreecommitdiff
path: root/cpp/src/IceUtil/Shared.cpp
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2015-02-18 19:23:23 +0100
committerJose <jose@zeroc.com>2015-02-18 19:23:23 +0100
commit7e570d78415b644cc4a4f7ed62029491609cbb1d (patch)
tree283fc9aec652376edbdf369d08844f9ae3a6824f /cpp/src/IceUtil/Shared.cpp
parent- Add IceLocatorDiscovery to the ruby and python extensions. (diff)
downloadice-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/IceUtil/Shared.cpp')
-rw-r--r--cpp/src/IceUtil/Shared.cpp102
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;