summaryrefslogtreecommitdiff
path: root/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp')
-rw-r--r--cpp/include/Ice/MetricsObserverI.h16
-rw-r--r--cpp/include/Ice/SlicedData.h5
-rw-r--r--cpp/include/IceUtil/Atomic.h178
-rw-r--r--cpp/include/IceUtil/Shared.h38
-rw-r--r--cpp/src/IceUtil/Shared.cpp61
5 files changed, 193 insertions, 105 deletions
diff --git a/cpp/include/Ice/MetricsObserverI.h b/cpp/include/Ice/MetricsObserverI.h
index 66e20afc2f4..8ae7afd5e93 100644
--- a/cpp/include/Ice/MetricsObserverI.h
+++ b/cpp/include/Ice/MetricsObserverI.h
@@ -11,6 +11,7 @@
#define ICEMX_METRICSOBSERVER_I_H
#include <IceUtil/StopWatch.h>
+#include <IceUtil/Atomic.h>
#include <Ice/Instrumentation.h>
#include <Ice/Endpoint.h>
@@ -430,7 +431,7 @@ public:
typedef std::vector<IceUtil::Handle<IceInternal::MetricsMapT<MetricsType> > > MetricsMapSeqType;
ObserverFactoryT(const IceInternal::MetricsAdminIPtr& metrics, const std::string& name) :
- _metrics(metrics), _name(name), _enabled(false)
+ _metrics(metrics), _name(name), _enabled(0)
{
_metrics->registerMap<MetricsType>(name, this);
}
@@ -517,12 +518,13 @@ public:
bool isEnabled() const
{
- return _enabled;
+ return _enabled != 0;
}
virtual void update()
{
UpdaterPtr updater;
+ bool enabled = false;
{
IceUtil::Mutex::Lock sync(*this);
if(!_metrics)
@@ -537,10 +539,10 @@ public:
_maps.push_back(IceUtil::Handle<IceInternal::MetricsMapT<MetricsType> >::dynamicCast(*p));
assert(_maps.back());
}
- _enabled = !_maps.empty();
+ enabled = !_maps.empty();
updater = _updater;
}
-
+ _enabled.exchange(enabled ? 1 : 0);
if(updater)
{
updater->update();
@@ -565,7 +567,11 @@ private:
IceInternal::MetricsAdminIPtr _metrics;
const std::string _name;
MetricsMapSeqType _maps;
- volatile bool _enabled;
+ //
+ // TODO: Replace by std::atomic<bool> when it becomes widely
+ // available.
+ //
+ IceUtilInternal::Atomic _enabled;
UpdaterPtr _updater;
};
diff --git a/cpp/include/Ice/SlicedData.h b/cpp/include/Ice/SlicedData.h
index 10e88900cdb..96ec59fd24c 100644
--- a/cpp/include/Ice/SlicedData.h
+++ b/cpp/include/Ice/SlicedData.h
@@ -64,11 +64,6 @@ public:
const SliceInfoSeq slices;
void __gcVisitMembers(IceInternal::GCVisitor&);
-
- void __decRefUnsafe()
- {
- --_ref;
- }
};
//
diff --git a/cpp/include/IceUtil/Atomic.h b/cpp/include/IceUtil/Atomic.h
new file mode 100644
index 00000000000..23d2577b404
--- /dev/null
+++ b/cpp/include/IceUtil/Atomic.h
@@ -0,0 +1,178 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef ICE_UTIL_ATOMIC_H
+#define ICE_UTIL_ATOMIC_H
+
+#if ((defined(ICE_CPP11) && defined(_MSC_VER) && (_MSC_VER > 1600)) || \
+ (defined(ICE_CPP11) && !defined(_MSC_VER)))
+# define ICE_CPP11_HAS_ATOMIC
+#endif
+
+#if defined(ICE_CPP11_HAS_ATOMIC)
+# include <atomic>
+#elif defined(ICE_USE_MUTEX_SHARED)
+
+# include <IceUtil/Mutex.h>
+
+// Using the gcc builtins requires gcc 4.1 or better. For Linux, i386
+// doesn't work. Apple is supported for all architectures. Sun only
+// supports sparc (32 and 64 bit).
+
+#elif ((defined(__GNUC__) && (((__GNUC__* 100) + __GNUC_MINOR__) >= 401)) || __clang__) && \
+ ((defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \
+ defined(__APPLE__) || \
+ (defined(__linux) && \
+ (defined(__i486) || defined(__i586) || \
+ defined(__i686) || defined(__x86_64))))
+
+# define ICE_HAS_GCC_BUILTINS
+
+#elif defined(_WIN32)
+// Nothing to include
+#else
+// Use a simple mutex
+# include <IceUtil/Mutex.h>
+#endif
+
+
+namespace IceUtilInternal
+{
+
+#ifdef ICE_CPP11_HAS_ATOMIC
+typedef std::atomic<int> Atomic;
+#else
+
+#if defined(_WIN32)
+//
+// volatile here is required by InterlockedExchangeXXX
+// family functions.
+//
+typedef volatile unsigned int ATOMIC_T;
+#else
+typedef int ATOMIC_T;
+#endif
+
+
+//
+// This is temporary and very partial placeholder for std::atomic,
+// which is not yet widely available.
+//
+class Atomic : public IceUtil::noncopyable
+{
+public:
+
+ Atomic() :
+ _ref(0)
+ {
+ }
+
+ Atomic(int desired) :
+ _ref(desired)
+ {
+ }
+
+ inline int fetch_add(int value)
+ {
+#if defined(_WIN32)
+ return InterlockedExchangeAdd(&_ref, value);
+#elif defined(ICE_HAS_GCC_BUILTINS)
+ return __sync_fetch_and_add(&_ref, value);
+#else
+ IceUtil::Mutex::Lock sync(_mutex);
+ int tmp = _ref;
+ _ref += value;
+ return tmp;
+#endif
+ }
+
+ inline int fetch_sub(int value)
+ {
+#if defined(_WIN32)
+ return InterlockedExchangeSubtract(&_ref, value);
+#elif defined(ICE_HAS_GCC_BUILTINS)
+ return __sync_fetch_and_sub(&_ref, value);
+#else
+ IceUtil::Mutex::Lock sync(_mutex);
+ ATOMIC_T tmp = _ref;
+ _ref -= value;
+ return tmp;
+#endif
+ }
+
+ inline int load() const
+ {
+#if defined(_WIN32)
+ return InterlockedExchangeAdd(const_cast<ATOMIC_T*>(&_ref), 0);
+#elif defined(ICE_HAS_GCC_BUILTINS)
+ return __sync_fetch_and_add(const_cast<ATOMIC_T*>(&_ref), 0);
+#else
+ IceUtil::Mutex::Lock sync(_mutex);
+ return _ref;
+#endif
+ }
+
+ inline int exchange(int value)
+ {
+#if defined(_WIN32)
+ return InterlockedExchange(&_ref, value);
+#elif defined(ICE_HAS_GCC_BUILTINS)
+ __sync_synchronize();
+ return __sync_lock_test_and_set(&_ref, value);
+#else
+ IceUtil::Mutex::Lock sync(_mutex);
+ int tmp = _ref;
+ _ref = value;
+ return _ref;
+#endif
+ }
+
+ inline int operator++()
+ {
+ return fetch_add(1) + 1;
+ }
+
+ inline int operator--()
+ {
+ return fetch_sub(1) - 1;
+ }
+
+ inline int operator++(int)
+ {
+ return fetch_add(1);
+ }
+
+ inline int operator--(int)
+ {
+ return fetch_sub(1);
+ }
+
+ inline operator int()
+ {
+ return load();
+ }
+
+ inline operator int() const
+ {
+ return load();
+ }
+
+private:
+
+ ATOMIC_T _ref;
+#if !defined(_WIN32) && !defined(ICE_HAS_GCC_BUILTINS)
+ Mutex _mutex;
+#endif
+};
+
+#endif
+
+}
+
+#endif
diff --git a/cpp/include/IceUtil/Shared.h b/cpp/include/IceUtil/Shared.h
index fdcbd5b29ad..1a7fe8d884e 100644
--- a/cpp/include/IceUtil/Shared.h
+++ b/cpp/include/IceUtil/Shared.h
@@ -11,32 +11,7 @@
#define ICE_UTIL_SHARED_H
#include <IceUtil/Config.h>
-
-#if defined(ICE_CPP11)
-# include <atomic>
-#elif defined(ICE_USE_MUTEX_SHARED)
-
-# include <IceUtil/Mutex.h>
-
-// Using the gcc builtins requires gcc 4.1 or better. For Linux, i386
-// doesn't work. Apple is supported for all architectures. Sun only
-// supports sparc (32 and 64 bit).
-
-#elif ((defined(__GNUC__) && (((__GNUC__* 100) + __GNUC_MINOR__) >= 401)) || __clang__) && \
- ((defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \
- defined(__APPLE__) || \
- (defined(__linux) && \
- (defined(__i486) || defined(__i586) || \
- defined(__i686) || defined(__x86_64))))
-
-# define ICE_HAS_GCC_BUILTINS
-
-#elif defined(_WIN32)
-// Nothing to include
-#else
-// Use a simple mutex
-# include <IceUtil/Mutex.h>
-#endif
+#include <IceUtil/Atomic.h>
//
// Base classes for reference counted types. The IceUtil::Handle
@@ -150,16 +125,7 @@ public:
protected:
-#if defined(ICE_CPP11)
- std::atomic<int> _ref;
-#elif defined(_WIN32)
- LONG _ref;
-#elif defined(ICE_HAS_GCC_BUILTINS)
- int _ref;
-#else
- int _ref;
- Mutex _mutex;
-#endif
+ IceUtilInternal::Atomic _ref;
unsigned char _flags;
};
diff --git a/cpp/src/IceUtil/Shared.cpp b/cpp/src/IceUtil/Shared.cpp
index f242ee8d986..f88068569e0 100644
--- a/cpp/src/IceUtil/Shared.cpp
+++ b/cpp/src/IceUtil/Shared.cpp
@@ -44,81 +44,24 @@ IceUtil::Shared::Shared(const Shared&) :
void
IceUtil::Shared::__incRef()
{
-#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)
-
-# ifndef NDEBUG
- int c =
-# endif
- __sync_fetch_and_add(&_ref, 1);
- assert(c >= 0);
-#else
- _mutex.lock();
assert(_ref >= 0);
++_ref;
- _mutex.unlock();
-#endif
}
void
IceUtil::Shared::__decRef()
{
-#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))
- {
- delete this;
- }
-#elif defined(ICE_HAS_GCC_BUILTINS)
- int c = __sync_fetch_and_sub(&_ref, 1);
- assert(c > 0);
- if(c == 1 && !(_flags & NoDelete))
- {
- delete this;
- }
-#else
- bool doDelete = false;
- _mutex.lock();
assert(_ref > 0);
- if(--_ref == 0)
- {
- doDelete = !(_flags & NoDelete);
- _flags |= NoDelete;
- }
- _mutex.unlock();
- if(doDelete)
+ if(--_ref == 0 && !(_flags & NoDelete))
{
delete this;
}
-#endif
}
int
IceUtil::Shared::__getRef() const
{
-#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);
-#else
- _mutex.lock();
- int ref = _ref;
- _mutex.unlock();
- return ref;
-#endif
+ return _ref;
}
void