OSDN Git Service

Atomic/SMP update, part 2. (manual to dalvik-dev)
authorAndy McFadden <fadden@android.com>
Thu, 27 May 2010 17:23:41 +0000 (10:23 -0700)
committerAndy McFadden <fadden@android.com>
Fri, 28 May 2010 21:09:48 +0000 (14:09 -0700)
Updated "generic" quasiatomic implementation to use atomic release store
instead of atomic swap when releasing the lock.

Track change to name of memory barrier.

Change-Id: I229fc2aec8996db07b84f2d1bcfbe4346a810d85

vm/Atomic.c
vm/Atomic.h

index 859a030..55b4cc9 100644 (file)
@@ -153,6 +153,10 @@ int64_t android_quasiatomic_read_64(volatile int64_t* addr) {
  * these must be initialized before being used, and
  * then you have the problem of lazily initializing
  * a mutex without any other synchronization primitive.
+ *
+ * TODO: these currently use sched_yield(), which is not guaranteed to
+ * do anything at all.  We need to use dvmIterativeSleep or a wait /
+ * notify mechanism if the initial attempt fails.
  */
 
 /* global spinlock for all 64-bit quasiatomic operations */
@@ -162,7 +166,7 @@ int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue,
         volatile int64_t* addr) {
     int result;
 
-    while (android_atomic_cmpxchg(0, 1, &quasiatomic_spinlock)) {
+    while (android_atomic_acquire_cas(0, 1, &quasiatomic_spinlock)) {
 #ifdef HAVE_WIN32_THREADS
         Sleep(0);
 #else
@@ -177,7 +181,7 @@ int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue,
         result = 1;
     }
 
-    android_atomic_swap(0, &quasiatomic_spinlock);
+    android_atomic_release_store(0, &quasiatomic_spinlock);
 
     return result;
 }
@@ -185,7 +189,7 @@ int android_quasiatomic_cmpxchg_64(int64_t oldvalue, int64_t newvalue,
 int64_t android_quasiatomic_read_64(volatile int64_t* addr) {
     int64_t result;
 
-    while (android_atomic_cmpxchg(0, 1, &quasiatomic_spinlock)) {
+    while (android_atomic_acquire_cas(0, 1, &quasiatomic_spinlock)) {
 #ifdef HAVE_WIN32_THREADS
         Sleep(0);
 #else
@@ -194,7 +198,7 @@ int64_t android_quasiatomic_read_64(volatile int64_t* addr) {
     }
 
     result = *addr;
-    android_atomic_swap(0, &quasiatomic_spinlock);
+    android_atomic_release_store(0, &quasiatomic_spinlock);
 
     return result;
 }
@@ -202,7 +206,7 @@ int64_t android_quasiatomic_read_64(volatile int64_t* addr) {
 int64_t android_quasiatomic_swap_64(int64_t value, volatile int64_t* addr) {
     int64_t result;
 
-    while (android_atomic_cmpxchg(0, 1, &quasiatomic_spinlock)) {
+    while (android_atomic_acquire_cas(0, 1, &quasiatomic_spinlock)) {
 #ifdef HAVE_WIN32_THREADS
         Sleep(0);
 #else
@@ -212,7 +216,7 @@ int64_t android_quasiatomic_swap_64(int64_t value, volatile int64_t* addr) {
 
     result = *addr;
     *addr = value;
-    android_atomic_swap(0, &quasiatomic_spinlock);
+    android_atomic_release_store(0, &quasiatomic_spinlock);
 
     return result;
 }
index aa2f103..27a5ea0 100644 (file)
 /*
  * Full memory barrier.  Ensures compiler ordering and SMP behavior.
  */
-#define MEM_BARRIER()   android_membar_full()
+#define MEM_BARRIER()   ANDROID_MEMBAR_FULL()
 
 /*
  * 32-bit atomic compare-and-swap macro.  Performs a memory barrier
  * before the swap (store-release).
  *
- * If *_addr equals "_old", replace it with "_new" and return nonzero.
+ * If *_addr equals "_old", replace it with "_new" and return nonzero
+ * (i.e. returns "false" if the operation fails).
  *
  * Underlying function is currently declared:
- * int android_atomic_cmpxchg(int32_t old, int32_t new, volatile int32_t* addr)
+ *   int release_cas(int32_t old, int32_t new, volatile int32_t* addr)
+ *
+ * TODO: rename macro to ATOMIC_RELEASE_CAS
  */
 #define ATOMIC_CMP_SWAP(_addr, _old, _new) \
-            (android_atomic_cmpxchg((_old), (_new), (_addr)) == 0)
+            (android_atomic_release_cas((_old), (_new), (_addr)) == 0)
 
 
 /*