New atomics from dalvik.

Change-Id: I00de43b180aaaf69f40f9bebddef641cffe949b7
diff --git a/src/atomic.cc b/src/atomic.cc
index f03cbbc..c373579 100644
--- a/src/atomic.cc
+++ b/src/atomic.cc
@@ -46,12 +46,24 @@
   return OSAtomicCompareAndSwap64Barrier(old_value, new_value, (int64_t*)addr) == 0;
 }
 
-int64_t QuasiAtomicSwap64(int64_t value, volatile int64_t* addr) {
-  int64_t oldValue;
+static inline int64_t QuasiAtomicSwap64Impl(int64_t value, volatile int64_t* addr) {
+  int64_t old_value;
   do {
-    oldValue = *addr;
-  } while (QuasiAtomicCas64(oldValue, value, addr));
-  return oldValue;
+    old_value = *addr;
+  } while (QuasiAtomicCas64(old_value, value, addr));
+  return old_value;
+}
+
+int64_t QuasiAtomicSwap64(int64_t value, volatile int64_t* addr) {
+  return QuasiAtomicSwap64Impl(value, addr);
+}
+
+int64_t QuasiAtomicSwap64Sync(int64_t value, volatile int64_t* addr) {
+  ANDROID_MEMBAR_STORE();
+  int64_t old_value = QuasiAtomicSwap64Impl(value, addr);
+  /* TUNING: barriers can be avoided on some architectures */
+  ANDROID_MEMBAR_FULL();
+  return old_value;
 }
 
 int64_t QuasiAtomicRead64(volatile const int64_t* addr) {
@@ -66,7 +78,7 @@
 #include <machine/cpu-features.h>
 
 #ifdef __ARM_HAVE_LDREXD
-int64_t QuasiAtomicSwap64(int64_t new_value, volatile int64_t* addr) {
+static inline int64_t QuasiAtomicSwap64Impl(int64_t new_value, volatile int64_t* addr) {
   int64_t prev;
   int status;
   do {
@@ -80,6 +92,17 @@
   return prev;
 }
 
+int64_t QuasiAtomicSwap64(int64_t new_value, volatile int64_t* addr) {
+  return QuasiAtomicSwap64Impl(new_value, addr);
+}
+
+int64_t QuasiAtomicSwap64Sync(int64_t new_value, volatile int64_t* addr) {
+  ANDROID_MEMBAR_STORE();
+  int64_t old_value = QuasiAtomicSwap64Impl(new_value, addr);
+  ANDROID_MEMBAR_FULL();
+  return old_value;
+}
+
 int QuasiAtomicCas64(int64_t old_value, int64_t new_value, volatile int64_t* addr) {
   int64_t prev;
   int status;
@@ -135,11 +158,16 @@
 
   pthread_mutex_lock(lock);
 
-  int64_t oldValue = *addr;
+  int64_t old_value = *addr;
   *addr = value;
 
   pthread_mutex_unlock(lock);
-  return oldValue;
+  return old_value;
+}
+
+int64_t QuasiAtomicSwap64Sync(int64_t value, volatile int64_t* addr) {
+  // Same as QuasiAtomicSwap64 - mutex handles barrier.
+  return QuasiAtomicSwap64(value, addr);
 }
 
 int QuasiAtomicCas64(int64_t old_value, int64_t new_value, volatile int64_t* addr) {
@@ -261,6 +289,11 @@
   return result;
 }
 
+int64_t QuasiAtomicSwap64Sync(int64_t value, volatile int64_t* addr) {
+  // Same as QuasiAtomicSwap64 - syscall handles barrier.
+  return QuasiAtomicSwap64(value, addr);
+}
+
 #endif /*NEED_QUASIATOMICS*/
 
 }  // namespace art
diff --git a/src/atomic.h b/src/atomic.h
index e3e4fc0..dab625e 100644
--- a/src/atomic.h
+++ b/src/atomic.h
@@ -30,16 +30,22 @@
  * quasiatomic operations that are performed on partially-overlapping
  * memory.
  *
- * None of these provide a memory barrier.
+ * Only the "Sync" functions provide a memory barrier.
  */
 
 /*
  * Swap the 64-bit value at "addr" with "value".  Returns the previous
- * value.
+ * value. No memory barriers.
  */
 int64_t QuasiAtomicSwap64(int64_t value, volatile int64_t* addr);
 
 /*
+ * Swap the 64-bit value at "addr" with "value".  Returns the previous
+ * value. Provides memory barriers.
+ */
+int64_t QuasiAtomicSwap64Sync(int64_t value, volatile int64_t* addr);
+
+/*
  * Read the 64-bit value at "addr".
  */
 int64_t QuasiAtomicRead64(volatile const int64_t* addr);