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

Reply via email to