merge from open-source master
diff --git a/libcutils/atomic-android-arm.S b/libcutils/atomic-android-arm.S
index f4299fd..4da6195 100644
--- a/libcutils/atomic-android-arm.S
+++ b/libcutils/atomic-android-arm.S
@@ -17,8 +17,7 @@
 #include <machine/cpu-features.h>
 
 /*
- * NOTE: these atomic operations are SMP safe on all architectures, 
- * except swap(), see below.
+ * NOTE: these atomic operations are SMP safe on all architectures. 
  */
 
 	.text
@@ -213,11 +212,18 @@
  * output: r0 = old value
  */
 
-/* FIXME: this is not safe on SMP systems 
- * a general way to do it is to use kernel_cmpxchg */
-
+/* replaced swp instruction with ldrex/strex for ARMv6 & ARMv7 */
 android_atomic_swap:
+#if defined (_ARM_HAVE_LDREX_STREX)
+1:  ldrex   r2, [r1]
+    strex   r3, r0, [r1]
+    teq     r3, #0
+    bne     1b
+    mov     r0, r2
+    mcr     p15, 0, r0, c7, c10, 5 /* or, use dmb */
+#else
     swp     r0, r0, [r1]
+#endif
     bx      lr
 
 /*