Atomic/SMP update, part 2.
Added new atomic functions, renamed some old ones. Some #defines have
been added for backward compatibility.
Merged the pre- and post-ARMv6 implementations into a single file.
Renamed the semi-private __android_membar_full_smp to USE_SCREAMING_CAPS
since that's more appropriate for a macro.
Added lots of comments.
Note Mac OS X primitives have not been tested.
Change-Id: If827260750aeb61ad5c2b760e30658e29dbb26f2
diff --git a/libcutils/atomic-android-sh.c b/libcutils/atomic-android-sh.c
index d95b02b..abe7d25 100644
--- a/libcutils/atomic-android-sh.c
+++ b/libcutils/atomic-android-sh.c
@@ -35,6 +35,9 @@
* ARM implementation, in this file above.
* We follow the fact that the initializer for mutex is a simple zero
* value.
+ *
+ * (3) These operations are NOT safe for SMP, as there is no currently
+ * no definition for a memory barrier operation.
*/
#include <pthread.h>
@@ -46,18 +49,35 @@
&_swap_locks[((unsigned)(void*)(addr) >> 3U) % SWAP_LOCK_COUNT]
-void android_atomic_write(int32_t value, volatile int32_t* addr) {
+int32_t android_atomic_acquire_load(volatile int32_t* addr)
+{
+ return *addr;
+}
+
+int32_t android_atomic_release_load(volatile int32_t* addr)
+{
+ return *addr;
+}
+
+void android_atomic_acquire_store(int32_t value, volatile int32_t* addr) {
int32_t oldValue;
do {
oldValue = *addr;
- } while (android_atomic_cmpxchg(oldValue, value, addr));
+ } while (android_atomic_release_cas(oldValue, value, addr));
+}
+
+void android_atomic_release_store(int32_t value, volatile int32_t* addr) {
+ int32_t oldValue;
+ do {
+ oldValue = *addr;
+ } while (android_atomic_release_cas(oldValue, value, addr));
}
int32_t android_atomic_inc(volatile int32_t* addr) {
int32_t oldValue;
do {
oldValue = *addr;
- } while (android_atomic_cmpxchg(oldValue, oldValue+1, addr));
+ } while (android_atomic_release_cas(oldValue, oldValue+1, addr));
return oldValue;
}
@@ -65,7 +85,7 @@
int32_t oldValue;
do {
oldValue = *addr;
- } while (android_atomic_cmpxchg(oldValue, oldValue-1, addr));
+ } while (android_atomic_release_cas(oldValue, oldValue-1, addr));
return oldValue;
}
@@ -73,7 +93,7 @@
int32_t oldValue;
do {
oldValue = *addr;
- } while (android_atomic_cmpxchg(oldValue, oldValue+value, addr));
+ } while (android_atomic_release_cas(oldValue, oldValue+value, addr));
return oldValue;
}
@@ -81,7 +101,7 @@
int32_t oldValue;
do {
oldValue = *addr;
- } while (android_atomic_cmpxchg(oldValue, oldValue&value, addr));
+ } while (android_atomic_release_cas(oldValue, oldValue&value, addr));
return oldValue;
}
@@ -89,11 +109,15 @@
int32_t oldValue;
do {
oldValue = *addr;
- } while (android_atomic_cmpxchg(oldValue, oldValue|value, addr));
+ } while (android_atomic_release_cas(oldValue, oldValue|value, addr));
return oldValue;
}
-int32_t android_atomic_swap(int32_t value, volatile int32_t* addr) {
+int32_t android_atomic_acquire_swap(int32_t value, volatile int32_t* addr) {
+ return android_atomic_release_swap(value, addr);
+}
+
+int32_t android_atomic_release_swap(int32_t value, volatile int32_t* addr) {
int32_t oldValue;
do {
oldValue = *addr;
@@ -101,7 +125,12 @@
return oldValue;
}
-int android_atomic_cmpxchg(int32_t oldvalue, int32_t newvalue,
+int android_atomic_acquire_cmpxchg(int32_t oldvalue, int32_t newvalue,
+ volatile int32_t* addr) {
+ return android_atomic_release_cmpxchg(oldValue, newValue, addr);
+}
+
+int android_atomic_release_cmpxchg(int32_t oldvalue, int32_t newvalue,
volatile int32_t* addr) {
int result;
pthread_mutex_t* lock = SWAP_LOCK(addr);
@@ -118,8 +147,3 @@
return result;
}
-int android_atomic_acquire_cmpxchg(int32_t oldvalue, int32_t newvalue,
- volatile int32_t* addr) {
- return android_atomic_cmpxchg(oldValue, newValue, addr);
-}
-