updated mongodb atomics patch

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Folks,

This is a work in progress. It builds on v7, but I've not tested yet.

We've a few dependency issues building this on F19 just now, but it will
build for v7 against 2.2.3 on F18 as well locally. If someone with more
knowledge of mongo would like to take a poke/test, cool. I have done a
literal port of the x86_64 implementation (hence it contains a few
superfluous bits intentionally). It'll need cleaning up.

Jon.
diff -urNp mongodb-src-r2.2.3_orig/src/mongo/bson/util/atomic_int.h mongodb-src-r2.2.3/src/mongo/bson/util/atomic_int.h
--- mongodb-src-r2.2.3_orig/src/mongo/bson/util/atomic_int.h	2013-01-31 10:18:33.000000000 -0500
+++ mongodb-src-r2.2.3/src/mongo/bson/util/atomic_int.h	2013-02-19 00:12:16.580841779 -0500
@@ -90,7 +90,9 @@ namespace mongo {
     void AtomicUInt::signedAdd(int by) {
         __sync_fetch_and_add(&x, by);
     }
-#elif defined(__GNUC__)  && (defined(__i386__) || defined(__x86_64__))
+#elif defined(__GNUC__)  && (defined(__i386__) || defined(__x86_64__) || defined(__arm__))
+
+#if defined(__i386__) || defined(__x86_64__)
     inline void AtomicUInt::set(unsigned newX) {
         asm volatile("mfence" ::: "memory");
         x = newX;
@@ -109,6 +111,31 @@ namespace mongo {
         );
         return r;
     }
+#endif
+
+#if defined(__arm__)
+    inline void AtomicUInt::set(unsigned newX) {
+	asm volatile("mcr p15, 0, r0, c7, c10, 5");
+        x = newX;
+    }
+
+    typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+    #define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0)
+
+    inline unsigned atomic_int_helper(volatile unsigned *x, int val) {
+    {
+        int old, new;
+
+        do {
+                old = *ptr;
+                new = old + val;
+        } while(__kuser_cmpxchg(old, new, ptr));
+
+        return old;
+    }
+
+#endif
+
     AtomicUInt AtomicUInt::operator++() {
         return atomic_int_helper(&x, 1)+1;
     }
diff -urNp mongodb-src-r2.2.3_orig/src/mongo/platform/atomic_intrinsics_gcc.h mongodb-src-r2.2.3/src/mongo/platform/atomic_intrinsics_gcc.h
--- mongodb-src-r2.2.3_orig/src/mongo/platform/atomic_intrinsics_gcc.h	2013-01-31 10:18:33.000000000 -0500
+++ mongodb-src-r2.2.3/src/mongo/platform/atomic_intrinsics_gcc.h	2013-02-19 11:21:29.988914574 -0500
@@ -14,14 +14,23 @@
  */
 
 /**
- * Implementation of the AtomicIntrinsics<T>::* operations for IA-32 and AMD64 systems using a
- * GCC-compatible compiler toolchain.
+ * Implementation of the AtomicIntrinsics<T>::* operations for IA-32, AMD64, and 32-bit ARM
+ * systems using a GCC-compatible compiler toolchain.
  */
 
 #pragma once
 
 #include <boost/utility.hpp>
 
+#if defined(__arm__)
+typedef int (__kuser_cmpxchg_t)(int oldval, int newval, volatile int *ptr);
+#define __kuser_cmpxchg (*(__kuser_cmpxchg_t *)0xffff0fc0)
+typedef int (__kuser_cmpxchg64_t)(const int64_t *oldval,
+                                  const int64_t *newval,
+                                  volatile int64_t *ptr);
+#define __kuser_cmpxchg64 (*(__kuser_cmpxchg64_t *)0xffff0f60)
+#endif
+
 namespace mongo {
 
     /**
@@ -37,48 +46,106 @@ namespace mongo {
         static T compareAndSwap(volatile T* dest, T expected, T newValue) {
 
             T result;
+
+#if defined(__i386__) || defined(__x86_64__)
             asm volatile ("lock cmpxchg %[src], %[dest]"
                           : [dest] "+m" (*dest),
                             "=a" (result)
                           : [src] "r" (newValue),
                             "a" (expected)
                           : "memory", "cc");
+#endif
+
+#if defined(__arm__)
+            if (__kuser_cmpxchg((int)expected, (int)newValue,
+                                (volatile int *)dest) == 0)
+		result = newValue;
+	    else
+		result = *dest;
+#endif
+
             return result;
         }
 
         static T swap(volatile T* dest, T newValue) {
 
             T result = newValue;
+
+#if defined(__i386__) || defined(__x86_64__)
             // No need for "lock" prefix on "xchg".
             asm volatile ("xchg %[r], %[dest]"
                           : [dest] "+m" (*dest),
                             [r] "+r" (result)
                           :
                           : "memory");
+#endif
+
+#if defined(__arm__)
+            do {
+                // nothing
+            } while (__kuser_cmpxchg((int)(*dest), (int)newValue,
+                                     (volatile int *)dest));
+#endif
+
             return result;
         }
 
         static T load(volatile const T* value) {
+
+#if defined(__i386__) || defined(__x86_64__)
             asm volatile ("mfence" ::: "memory");
             T result = *value;
             asm volatile ("mfence" ::: "memory");
+#endif
+
+#if defined(__arm__)
+            asm volatile("mcr p15, 0, r0, c7, c10, 5");
+            T result = *value;
+            asm volatile("mcr p15, 0, r0, c7, c10, 5");
+#endif
+
             return result;
         }
 
         static void store(volatile T* dest, T newValue) {
+
+#if defined(__i386__) || defined(__x86_64__)
             asm volatile ("mfence" ::: "memory");
             *dest = newValue;
             asm volatile ("mfence" ::: "memory");
+#endif
+
+#if defined(__arm__)
+            asm volatile("mcr p15, 0, r0, c7, c10, 5");
+            *dest = newValue;
+            asm volatile("mcr p15, 0, r0, c7, c10, 5");
+#endif
+
         }
 
         static T fetchAndAdd(volatile T* dest, T increment) {
 
             T result = increment;
+
+#if defined(__i386__) || defined(__x86_64__)
             asm volatile ("lock xadd %[src], %[dest]"
                           : [dest] "+m" (*dest),
                             [src] "+r" (result)
                           :
                           : "memory", "cc");
+#endif
+
+#if defined(__arm__)
+            int old;
+
+            do {
+                old = (int)(*dest);
+            } while(__kuser_cmpxchg((int)old, (int)(old+increment),
+                                    (volatile int *)dest));
+
+            result = old;
+#endif
+
             return result;
         }
 
@@ -101,6 +168,8 @@ namespace mongo {
     public:
         static T compareAndSwap(volatile T* dest, T expected, T newValue) {
             T result = expected;
+
+#if defined(__i386__) || defined(__x86_64__)
             asm volatile ("push %%eax\n"
                           "push %%ebx\n"
                           "push %%ecx\n"
@@ -121,6 +190,16 @@ namespace mongo {
                             "D" (&result),
                             "d" (&newValue)
                           : "memory", "cc");
+#endif
+
+#if defined(__arm__)
+            if (__kuser_cmpxchg64((const int64_t *)&expected, (const int64_t *)&newValue,
+				  (volatile int64_t *)dest) == 0)
+                result = newValue;
+            else
+                result = *dest;
+#endif
+
             return result;
         }
 
diff -urNp mongodb-src-r2.2.3_orig/src/mongo/platform/bits.h mongodb-src-r2.2.3/src/mongo/platform/bits.h
--- mongodb-src-r2.2.3_orig/src/mongo/platform/bits.h	2013-01-31 10:18:33.000000000 -0500
+++ mongodb-src-r2.2.3/src/mongo/platform/bits.h	2013-02-19 11:11:14.537944114 -0500
@@ -21,7 +21,7 @@
 
 #if defined(__x86_64__) || defined(__amd64__) || defined(_WIN64)
 #define MONGO_PLATFORM_64
-#elif defined(__i386__) || defined(_WIN32)
+#elif defined(__i386__) || defined(_WIN32) || defined(__arm__)
 #define MONGO_PLATFORM_32
 #else
 #error "unknown platform"
_______________________________________________
arm mailing list
arm@xxxxxxxxxxxxxxxxxxxxxxx
https://admin.fedoraproject.org/mailman/listinfo/arm

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux ARM (Vger)]     [Linux ARM]     [ARM Kernel]     [Fedora User Discussion]     [Older Fedora Users Discussion]     [Fedora Advisory Board]     [Fedora Security]     [Fedora Maintainers]     [Fedora Devel Java]     [Fedora Legacy]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Mentors]     [Fedora Package Announce]     [Fedora Package Review]     [Fedora Music]     [Fedora Packaging]     [Centos]     [Fedora SELinux]     [Coolkey]     [Yum Users]     [Tux]     [Yosemite News]     [Linux Apps]     [KDE Users]     [Fedora Tools]     [Fedora Art]     [Fedora Docs]     [Asterisk PBX]

Powered by Linux