about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMaxim Kuvyrkov <maxim@codesourcery.com>2012-08-13 19:55:34 -0700
committerMaxim Kuvyrkov <maxim@codesourcery.com>2012-08-13 19:55:34 -0700
commit8f12da979523f5f95190d41fcef7e833b773a92d (patch)
tree0db3dca2e28b626778f6886c8bf9ac7834e76569
parent51a9ba860ae3305d475f43f568e8fa51b8a53b6e (diff)
downloadglibc-8f12da979523f5f95190d41fcef7e833b773a92d.tar.gz
glibc-8f12da979523f5f95190d41fcef7e833b773a92d.tar.xz
glibc-8f12da979523f5f95190d41fcef7e833b773a92d.zip
Add explicit acquire/release semantics to MIPS' atomic_exchange_and_add.
-rw-r--r--ports/ChangeLog.mips11
-rw-r--r--ports/sysdeps/mips/bits/atomic.h22
2 files changed, 24 insertions, 9 deletions
diff --git a/ports/ChangeLog.mips b/ports/ChangeLog.mips
index 0c503bcafb..f8a9af198c 100644
--- a/ports/ChangeLog.mips
+++ b/ports/ChangeLog.mips
@@ -1,3 +1,14 @@
+2012-08-13  Maxim Kuvyrkov  <maxim@codesourcery.com>
+
+        [__GNUC_PREREQ (4, 8)]
+        (atomic_exchange_and_add): Split into ...
+        (atomic_exchange_and_add_acq, atomic_exchange_and_add_rel): ... these.
+        New atomic macros.
+        [!__GNUC_PREREQ (4, 8)]
+        (atomic_exchange_and_add): Split into ...
+        (atomic_exchange_and_add_acq, atomic_exchange_and_add_rel): ... these.
+        New atomic macros.
+
 2012-08-09  Joseph Myers  <joseph@codesourcery.com>
 
 	* sysdeps/unix/sysv/linux/mips/kernel-features.h
diff --git a/ports/sysdeps/mips/bits/atomic.h b/ports/sysdeps/mips/bits/atomic.h
index b0942737dd..749e166908 100644
--- a/ports/sysdeps/mips/bits/atomic.h
+++ b/ports/sysdeps/mips/bits/atomic.h
@@ -193,11 +193,13 @@ typedef uintmax_t uatomic_max_t;
   __atomic_fetch_add (mem, value, model)
 # endif
 
-/* ??? Barrier semantics for atomic_exchange_and_add appear to be
-   undefined.  Use full barrier for now, as that's safe.  */
-# define atomic_exchange_and_add(mem, value)				\
+# define atomic_exchange_and_add_acq(mem, value)			\
   __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
-		       __ATOMIC_ACQ_REL)
+		       __ATOMIC_ACQUIRE)
+
+# define atomic_exchange_and_add_rel(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       __ATOMIC_RELEASE)
 #else /* !__GNUC_PREREQ (4, 8) */
 /* This implementation using inline assembly will be removed once glibc
    requires GCC 4.8 or later to build.  */
@@ -434,11 +436,13 @@ typedef uintmax_t uatomic_max_t;
   __prev; })
 # endif
 
-/* ??? Barrier semantics for atomic_exchange_and_add appear to be 
-   undefined.  Use full barrier for now, as that's safe.  */
-# define atomic_exchange_and_add(mem, value) \
-  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	      \
-		       MIPS_SYNC_STR, MIPS_SYNC_STR)
+# define atomic_exchange_and_add_acq(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       "", MIPS_SYNC_STR)
+
+# define atomic_exchange_and_add_rel(mem, value)			\
+  __atomic_val_bysize (__arch_exchange_and_add, int, mem, value,	\
+		       MIPS_SYNC_STR, "")
 #endif /* __GNUC_PREREQ (4, 8) */
 
 /* TODO: More atomic operations could be implemented efficiently; only the