diff options
author | Matthew Newhook <matthew@zeroc.com> | 2009-12-08 19:54:47 -0330 |
---|---|---|
committer | Matthew Newhook <matthew@zeroc.com> | 2009-12-08 19:54:47 -0330 |
commit | 87c2b141d0fe879562c8732ca209212306ab8a7d (patch) | |
tree | c4d909e9dc1d0491cdb1f9234e2ab1c6418be5c1 /cpp | |
parent | fixing build.xml for fileLock test (diff) | |
download | ice-87c2b141d0fe879562c8732ca209212306ab8a7d.tar.bz2 ice-87c2b141d0fe879562c8732ca209212306ab8a7d.tar.xz ice-87c2b141d0fe879562c8732ca209212306ab8a7d.zip |
http://bugzilla/bugzilla/show_bug.cgi?id=4203 - Use gcc native atomic functions
Diffstat (limited to 'cpp')
-rw-r--r-- | cpp/config/Make.rules.Linux | 5 | ||||
-rw-r--r-- | cpp/include/IceUtil/Shared.h | 17 | ||||
-rw-r--r-- | cpp/src/IceUtil/Shared.cpp | 13 |
3 files changed, 34 insertions, 1 deletions
diff --git a/cpp/config/Make.rules.Linux b/cpp/config/Make.rules.Linux index 5071876805d..5ec54bc32d3 100644 --- a/cpp/config/Make.rules.Linux +++ b/cpp/config/Make.rules.Linux @@ -13,6 +13,7 @@ USE_SPARC_ASM = irrelevant MACHINE = $(shell uname -m) +SUSE_i586 = $(shell grep i586 /etc/SuSE-release 2>/dev/null) # # Default compiler is c++ (aka g++). @@ -40,6 +41,10 @@ endif ifeq ($(CXX),c++) + ifneq ($(SUSE_i586),) + CXXARCHFLAGS += -march=i586 + endif + ifeq ($(MACHINE),sparc64) # # We are an ultra, at least, and so have the atomic instructions diff --git a/cpp/include/IceUtil/Shared.h b/cpp/include/IceUtil/Shared.h index a23a55fb3ae..64e4c51a74d 100644 --- a/cpp/include/IceUtil/Shared.h +++ b/cpp/include/IceUtil/Shared.h @@ -13,9 +13,24 @@ #include <IceUtil/Config.h> #if 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 __GNUC__ >= 4 && __GNUC_MINOR__ >= 1 && \ + ((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(__APPLE__) || defined(__linux) || defined(__FreeBSD__)) && (defined(__i386) || defined(__x86_64)) && !defined(__ICC) + # define ICE_HAS_ATOMIC_FUNCTIONS #elif defined(_WIN32) @@ -119,7 +134,7 @@ protected: #if defined(_WIN32) LONG _ref; -#elif defined(ICE_HAS_ATOMIC_FUNCTIONS) +#elif defined(ICE_HAS_ATOMIC_FUNCTIONS) || defined(ICE_HAS_GCC_BUILTINS) volatile int _ref; #else int _ref; diff --git a/cpp/src/IceUtil/Shared.cpp b/cpp/src/IceUtil/Shared.cpp index 2c0205a4265..c25e8e74ee6 100644 --- a/cpp/src/IceUtil/Shared.cpp +++ b/cpp/src/IceUtil/Shared.cpp @@ -114,6 +114,9 @@ IceUtil::Shared::__incRef() #if defined(_WIN32) assert(InterlockedExchangeAdd(&_ref, 0) >= 0); InterlockedIncrement(&_ref); +#elif defined(ICE_HAS_GCC_BUILTINS) + int c = __sync_fetch_and_add(&_ref, 1); + assert(c >= 0); #elif defined(ICE_HAS_ATOMIC_FUNCTIONS) assert(IceUtilInternal::atomicExchangeAdd(&_ref, 0) >= 0); IceUtilInternal::atomicInc(&_ref); @@ -135,6 +138,14 @@ IceUtil::Shared::__decRef() _noDelete = true; delete this; } +#elif defined(ICE_HAS_GCC_BUILTINS) + int c = __sync_fetch_and_sub(&_ref, 1); + assert(c > 0); + if(c == 1 && !_noDelete) + { + _noDelete = true; + delete this; + } #elif defined(ICE_HAS_ATOMIC_FUNCTIONS) assert(IceUtilInternal::atomicExchangeAdd(&_ref, 0) > 0); if(IceUtilInternal::atomicDecAndTest(&_ref) && !_noDelete) @@ -164,6 +175,8 @@ IceUtil::Shared::__getRef() const { #if 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 |