aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--xbmc/threads/Atomics.cpp159
1 files changed, 115 insertions, 44 deletions
diff --git a/xbmc/threads/Atomics.cpp b/xbmc/threads/Atomics.cpp
index b3c4702239..d200859d7f 100644
--- a/xbmc/threads/Atomics.cpp
+++ b/xbmc/threads/Atomics.cpp
@@ -46,6 +46,30 @@ long cas(volatile long *pAddr, long expectedVal, long swapVal)
return prev;
}
+#elif defined(__arm__)
+
+long cas(volatile long* pAddr, long expectedVal, long swapVal)
+{
+ register long prev;
+ asm volatile (
+ "1: \n"
+ "ldrex %0, [%1] \n" /* Load the current value of *pAddr(%1) into prev (%0) and lock pAddr, */
+ "cmp %0, %2 \n" /* Verify that the current value (%0) == old value (%2) */
+ "bne 2f \n" /* Bail if the two values are not equal [not as expected] */
+ "strex r1, %3, [%1] \n"
+ "cmp r1, #0 \n"
+ "bne 1b \n"
+ "2: "
+ : "=&r" (prev)
+ : "r"(pAddr), "r"(expectedVal),"r"(swapVal)
+ : "r1"
+ );
+ return prev;
+}
+
+#elif defined(__mips__)
+// TODO:
+
#elif defined(WIN32)
long cas(volatile long* pAddr, long expectedVal, long swapVal)
@@ -69,14 +93,6 @@ long cas(volatile long* pAddr, long expectedVal, long swapVal)
return prev;
}
-#elif defined(__arm__)
-
-long cas(volatile long* pAddr, long expectedVal, long swapVal)
-{
- // __sync_val_compare_and_swap -> GCC >= 401
- return __sync_val_compare_and_swap(pAddr, expectedVal, swapVal);
-}
-
#else // Linux / OSX86 (GCC)
long cas(volatile long* pAddr,long expectedVal, long swapVal)
@@ -98,9 +114,9 @@ long cas(volatile long* pAddr,long expectedVal, long swapVal)
// 64-bit atomic compare-and-swap
// Returns previous value of *pAddr
///////////////////////////////////////////////////////////////////////////
-#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) // PowerPC & ARM
+#if defined(__ppc__) || defined(__powerpc__) || defined(__arm__) || defined(__mips__) // PowerPC, ARM, and MIPS
-// Not available
+// Not available/required
#elif defined(WIN32)
@@ -171,6 +187,28 @@ long AtomicIncrement(volatile long* pAddr)
return val;
}
+#elif defined(__arm__)
+
+long AtomicIncrement(volatile long* pAddr)
+{
+ register long val;
+ asm volatile (
+ "1: \n"
+ "ldrex %0, [%1] \n" // (val = *pAddr)
+ "add %0, #1 \n" // (val += 1)
+ "strex r1, %0, [%1] \n"
+ "cmp r1, #0 \n"
+ "bne 1b \n"
+ : "=&r" (val)
+ : "r"(pAddr)
+ : "r1"
+ );
+ return val;
+}
+
+#elif defined(__mips__)
+// TODO:
+
#elif defined(WIN32)
long AtomicIncrement(volatile long* pAddr)
@@ -186,14 +224,6 @@ long AtomicIncrement(volatile long* pAddr)
return val;
}
-#elif defined(__arm__)
-
-long AtomicIncrement(volatile long* pAddr)
-{
- // __sync_fetch_and_add -> GCC >= 401
- return __sync_fetch_and_add(pAddr, 1);
-}
-
#else // Linux / OSX86 (GCC)
long AtomicIncrement(volatile long* pAddr)
@@ -208,7 +238,6 @@ long AtomicIncrement(volatile long* pAddr)
return reg;
}
-
#endif
///////////////////////////////////////////////////////////////////////////
@@ -235,6 +264,28 @@ long AtomicAdd(volatile long* pAddr, long amount)
return val;
}
+#elif defined(__arm__)
+
+long AtomicAdd(volatile long* pAddr, long amount)
+{
+ register long val;
+ asm volatile (
+ "1: \n"
+ "ldrex %0, [%1] \n" // (val = *pAddr)
+ "add %0, %2 \n" // (val += amount)
+ "strex r1, %0, [%1] \n"
+ "cmp r1, #0 \n"
+ "bne 1b \n"
+ : "=&r" (val)
+ : "r"(pAddr), "r"(amount)
+ : "r1"
+ );
+ return val;
+}
+
+#elif defined(__mips__)
+// TODO:
+
#elif defined(WIN32)
long AtomicAdd(volatile long* pAddr, long amount)
@@ -250,14 +301,6 @@ long AtomicAdd(volatile long* pAddr, long amount)
return amount;
}
-#elif defined(__arm__)
-
-long AtomicAdd(volatile long* pAddr, long amount)
-{
- // TODO: ARM Assembler
- return 0;
-}
-
#else // Linux / OSX86 (GCC)
long AtomicAdd(volatile long* pAddr, long amount)
@@ -297,6 +340,28 @@ long AtomicDecrement(volatile long* pAddr)
return val;
}
+#elif defined(__arm__)
+
+long AtomicDecrement(volatile long* pAddr)
+{
+ register long val;
+ asm volatile (
+ "1: \n"
+ "ldrex %0, [%1] \n" // (val = *pAddr)
+ "sub %0, #1 \n" // (val -= 1)
+ "strex r1, %0, [%1] \n"
+ "cmp r1, #0 \n"
+ "bne 1b \n"
+ : "=&r" (val)
+ : "r"(pAddr)
+ : "r1"
+ );
+
+ return val;
+}
+
+#elif defined(__mips__)
+// TODO:
#elif defined(WIN32)
@@ -313,14 +378,6 @@ long AtomicDecrement(volatile long* pAddr)
return val;
}
-#elif defined(__arm__)
-
-long AtomicDecrement(volatile long* pAddr)
-{
- // __sync_fetch_and_add -> GCC >= 401
- return __sync_fetch_and_add(pAddr, -1);
-}
-
#else // Linux / OSX86 (GCC)
long AtomicDecrement(volatile long* pAddr)
@@ -335,7 +392,6 @@ long AtomicDecrement(volatile long* pAddr)
return reg;
}
-
#endif
///////////////////////////////////////////////////////////////////////////
@@ -362,6 +418,29 @@ long AtomicSubtract(volatile long* pAddr, long amount)
return val;
}
+#elif defined(__arm__)
+
+long AtomicSubtract(volatile long* pAddr, long amount)
+{
+ register long val;
+ asm volatile (
+ "1: \n"
+ "ldrex %0, [%1] \n" // (val = *pAddr)
+ "sub %0, %2 \n" // (val -= amount)
+ "strex r1, %0, [%1] \n"
+ "cmp r1, #0 \n"
+ "bne 1b \n"
+ : "=&r" (val)
+ : "r"(pAddr), "r"(amount)
+ : "r1"
+ );
+
+ return val;
+}
+
+#elif defined(__mips__)
+// TODO:
+
#elif defined(WIN32)
long AtomicSubtract(volatile long* pAddr, long amount)
@@ -378,14 +457,6 @@ long AtomicSubtract(volatile long* pAddr, long amount)
return amount;
}
-#elif defined(__arm__)
-
-long AtomicSubtract(volatile long* pAddr, long amount)
-{
- // TODO: ARM Assembler
- return 0;
-}
-
#else // Linux / OSX86 (GCC)
long AtomicSubtract(volatile long* pAddr, long amount)