Module: sems Branch: master Commit: df9524d8e0d8537a93ac2df3e20b0966dab65799 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sems/?a=commit;h=df9524d8e0d8537a93ac2df3e20b0966dab65799
Author: Peter Lemenkov <[email protected]> Committer: Raphael Coeffic <[email protected]> Date: Wed Sep 29 11:42:29 2010 +0400 Fix for architectures w/o atomic built-in functions --- core/atomic_types.h | 113 ++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 99 insertions(+), 14 deletions(-) diff --git a/core/atomic_types.h b/core/atomic_types.h index 4075eb4..474f169 100644 --- a/core/atomic_types.h +++ b/core/atomic_types.h @@ -1,31 +1,49 @@ #ifndef _atomic_types_h_ #define _atomic_types_h_ -#if defined(__GNUC__) -# if defined(__GNUC_PATCHLEVEL__) -# define __GNUC_VERSION__ (__GNUC__ * 10000 \ - + __GNUC_MINOR__ * 100 \ - + __GNUC_PATCHLEVEL__) -# else -# define __GNUC_VERSION__ (__GNUC__ * 10000 \ - + __GNUC_MINOR__ * 100) -# endif +#if (__GNUC__ > 4) || \ + (__GNUC__ == 4 && __GNUC_MINOR__ >= 1) && \ + ( \ + (defined(__APPLE__) && \ + ( \ + defined(__ppc__) || \ + defined(__i386__) || \ + defined(__x86_64__) \ + ) \ + ) || \ + (defined(__linux__) && \ + ( \ + (defined(__i386__) && (defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8))) || \ + defined(__ia64__) || \ + defined(__x86_64__) || \ + (defined(__powerpc__) && !defined(__powerpc64__)) || \ + defined(__alpha) \ + ) \ + ) \ + ) +#define HAVE_ATOMIC_CAS 1 #else -#error Unsupported compiler -#endif - -#if __GNUC_VERSION__ < 40101 -#error GCC version >= 4.1.1 is required for proper atomic operations +#warning Compare and Swap is not supported on this architecture +#define HAVE_ATOMIC_CAS 0 #endif #include <assert.h> #include "log.h" +#if !HAVE_ATOMIC_CAS +#include "AmThread.h" +#endif + + // 32 bit unsigned integer class atomic_int +#if !HAVE_ATOMIC_CAS + : protected AmMutex +#endif { volatile unsigned int i; + public: atomic_int() : i(0) {} @@ -37,6 +55,7 @@ public: return i; } +#if HAVE_ATOMIC_CAS // ++i; unsigned int inc() { return __sync_add_and_fetch(&i,1); @@ -46,6 +65,25 @@ public: unsigned int dec() { return __sync_sub_and_fetch(&i,1); } +#else // if HAVE_ATOMIC_CAS + // ++i; + unsigned int inc() { + unsigned int res; + lock(); + res = ++i; + unlock(); + return res; + } + + // --i; + unsigned int dec() { + unsigned int res; + lock(); + res = --i; + unlock(); + return res; + } +#endif // return --ll != 0; bool dec_and_test() { @@ -55,10 +93,14 @@ public: // 64 bit unsigned integer class atomic_int64 +#if !HAVE_ATOMIC_CAS + : protected AmMutex +#endif { volatile unsigned long long ll; public: +#if HAVE_ATOMIC_CAS void set(unsigned long long val) { #if !defined(__LP64__) || !__LP64__ unsigned long long tmp_ll; @@ -95,6 +137,49 @@ public: return __sync_sub_and_fetch(&ll,1); } +#else // if HAVE_ATOMIC_CAS + + void set(unsigned long long val) { +#if !defined(__LP64__) || !__LP64__ + this->lock(); + ll = val; + unlock(); +#else + ll = val; +#endif + } + + unsigned long long get() { +#if !defined(__LP64__) || !__LP64__ + unsigned long long tmp_ll; + lock(); + tmp_ll = ll; + unlock(); + return tmp_ll; +#else + return ll; +#endif + } + + // returns ++ll; + unsigned long long inc() { + unsigned long long res; + lock(); + res = ++ll; + unlock(); + return res; + } + + // returns --ll; + unsigned long long dec() { + unsigned long long res; + lock(); + res = --ll; + unlock(); + return res; + } +#endif + // return --ll == 0; bool dec_and_test() { return dec() == 0; _______________________________________________ Semsdev mailing list [email protected] http://lists.iptel.org/mailman/listinfo/semsdev
