This is the mail archive of the libc-ports@sources.redhat.com mailing list for the libc-ports project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[ARM] bits/atomic.h and GCC atomic builtins


Hi,

This patch enhances the ARM version of bits/atomic.h to make use of the atomic 
builtins provided by GCC in case the backend provides a pattern to do this 
efficiently. Ok to apply?

Regards
Ken
diff --git a/ChangeLog.arm b/ChangeLog.arm
index 69a28c6..84062d6 100644
--- a/ChangeLog.arm
+++ b/ChangeLog.arm
@@ -1,3 +1,13 @@
+2010-11-12  Ken Werner  <ken.werner@de.ibm.com>
+
+	* sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h (atomic_full_barrier,
+	__arch_compare_and_exchange_val_32_acq): Use the atomic builtins
+	provided by GCC if __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 is defined.
+	(__arch_compare_and_exchange_val_8_acq,
+	__arch_compare_and_exchange_val_16_acq,
+	__arch_compare_and_exchange_val_64_acq): Use the GCC atomic builtins
+        if compiled with GCC 4.4 or later.
+
 2010-10-19  Joseph Myers  <joseph@codesourcery.com>
 
 	* sysdeps/arm/bits/mathdef.h (FP_FAST_FMA, FP_FAST_FMAF,
diff --git a/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h b/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
index b0586ea..18ca7c2 100644
--- a/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
+++ b/sysdeps/unix/sysv/linux/arm/nptl/bits/atomic.h
@@ -37,7 +37,12 @@ typedef uintmax_t uatomic_max_t;
 
 void __arm_link_error (void);
 
-#ifdef __thumb2__
+/* Use the atomic builtins provided by GCC in case the backend provides
+   a pattern to do this efficiently.  */
+
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#define atomic_full_barrier() __sync_synchronize ()
+#elif defined __thumb2__
 #define atomic_full_barrier() \
      __asm__ __volatile__						      \
 	     ("movw\tip, #0x0fa0\n\t"					      \
@@ -58,17 +63,32 @@ void __arm_link_error (void);
    current architecture, either via cleverness on pre-ARMv6 or via
    ldrex / strex on ARMv6.  */
 
+#ifdef GNUC_PREREQ (4, 4)
+/* Use the atomic builtins provided by GCC version 4.4 and later.  */
+#define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
+  __sync_val_compare_and_swap ((mem), (oldval), (newval))
+#define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
+  __sync_val_compare_and_swap ((mem), (oldval), (newval))  
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+  __sync_val_compare_and_swap ((mem), (oldval), (newval))  
+#else
 #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
   ({ __arm_link_error (); oldval; })
-
 #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
   ({ __arm_link_error (); oldval; })
+#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
+  ({ __arm_link_error (); oldval; })
+#endif
+
+#ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
+  __sync_val_compare_and_swap ((mem), (oldval), (newval))
 
 /* It doesn't matter what register is used for a_oldval2, but we must
    specify one to work around GCC PR rtl-optimization/21223.  Otherwise
    it may cause a_oldval or a_tmp to be moved to a different register.  */
 
-#ifdef __thumb2__
+#elif defined __thumb2__
 /* Thumb-2 has ldrex/strex.  However it does not have barrier instructions,
    so we still need to use the kernel helper.  */
 #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
@@ -118,5 +138,3 @@ void __arm_link_error (void);
      a_tmp; })
 #endif
 
-#define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
-  ({ __arm_link_error (); oldval; })

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]