2010-02-19 Ivan Maidanski <ivmai@mail.ru> (mostly really Patrick Marlier)
authorivmai <ivmai>
Fri, 19 Feb 2010 17:12:05 +0000 (17:12 +0000)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 25 Jul 2011 12:03:25 +0000 (16:03 +0400)
* src/atomic_ops/sysdeps/gcc/x86.h (AO_compare_and_swap_full):
Use __sync_bool_compare_and_swap() if AO_USE_SYNC_CAS_BUILTIN.
* src/atomic_ops/sysdeps/gcc/x86_64.h (AO_compare_and_swap_full):
Ditto.
* src/atomic_ops.h (AO_USE_SYNC_CAS_BUILTIN): New macro defined
if GCC v4.2+ or Intel compiler v11.1+ (only for amd64).
* src/atomic_ops.h: Include GCC-specific sysdeps files for Intel
compiler in GCC compatible mode (only for x86 and amd64).

ChangeLog
src/atomic_ops.h
src/atomic_ops/sysdeps/gcc/x86.h
src/atomic_ops/sysdeps/gcc/x86_64.h

index f57e2ce..85b8ca0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2010-02-19  Ivan Maidanski <ivmai@mail.ru> (mostly really Patrick Marlier)
+
+       * src/atomic_ops/sysdeps/gcc/x86.h (AO_compare_and_swap_full):
+       Use __sync_bool_compare_and_swap() if AO_USE_SYNC_CAS_BUILTIN.
+       * src/atomic_ops/sysdeps/gcc/x86_64.h (AO_compare_and_swap_full):
+       Ditto.
+       * src/atomic_ops.h (AO_USE_SYNC_CAS_BUILTIN): New macro defined
+       if GCC v4.2+ or Intel compiler v11.1+ (only for amd64).
+       * src/atomic_ops.h: Include GCC-specific sysdeps files for Intel
+       compiler in GCC compatible mode (only for x86 and amd64).
+
 2010-02-18  Ivan Maidanski <ivmai@mail.ru>
 
        * src/atomic_ops/sysdeps/gcc/x86_64.h (AO_nop_full): Don't check
index 30d045e..d3e9bb7 100644 (file)
 #if defined(__GNUC__) && !defined(AO_USE_PTHREAD_DEFS) \
     && !defined(__INTEL_COMPILER)
 # if defined(__i386__)
+    /* We don't define AO_USE_SYNC_CAS_BUILTIN for x86 here because     */
+    /* it might require specifying additional options (like -march)     */
+    /* or additional link libraries (if -march is not specified).       */
 #   include "atomic_ops/sysdeps/gcc/x86.h"
 # endif /* __i386__ */
 # if defined(__x86_64__)
+#   if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+      /* It is safe to use __sync CAS built-in on this architecture.    */
+#     define AO_USE_SYNC_CAS_BUILTIN
+#   endif
 #   include "atomic_ops/sysdeps/gcc/x86_64.h"
 # endif /* __x86_64__ */
 # if defined(__ia64__)
 #   include "atomic_ops/sysdeps/icc/ia64.h"
 #   define AO_GENERALIZE_TWICE
 # endif
+# if defined(__GNUC__)
+    /* Intel Compiler in GCC compatible mode */
+#   if defined(__i386__)
+#     include "atomic_ops/sysdeps/gcc/x86.h"
+#   endif /* __i386__ */
+#   if defined(__x86_64__)
+#     if __INTEL_COMPILER > 1110
+#       define AO_USE_SYNC_CAS_BUILTIN
+#     endif
+#     include "atomic_ops/sysdeps/gcc/x86_64.h"
+#   endif /* __x86_64__ */
+# endif
 #endif
 
 #if defined(_HPUX_SOURCE) && !defined(__GNUC__) && !defined(AO_USE_PTHREAD_DEFS)
index faf053b..8f73ac6 100644 (file)
@@ -121,14 +121,17 @@ AO_test_and_set_full(volatile AO_TS_t *addr)
 
 /* Returns nonzero if the comparison succeeded. */
 AO_INLINE int
-AO_compare_and_swap_full(volatile AO_t *addr,
-                             AO_t old, AO_t new_val)
+AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
 {
-  char result;
-  __asm__ __volatile__("lock; cmpxchgl %3, %0; setz %1"
-                       : "=m"(*addr), "=a"(result)
-                       : "m"(*addr), "r" (new_val), "a"(old) : "memory");
-  return (int) result;
+# ifdef AO_USE_SYNC_CAS_BUILTIN
+    return (int)__sync_bool_compare_and_swap(addr, old, new_val);
+# else
+    char result;
+    __asm__ __volatile__("lock; cmpxchgl %3, %0; setz %1"
+                         : "=m" (*addr), "=a" (result)
+                         : "m" (*addr), "r" (new_val), "a" (old) : "memory");
+    return (int)result;
+# endif
 }
 
 #define AO_HAVE_compare_and_swap_full
index 61cf8f2..2274a2d 100644 (file)
@@ -121,7 +121,7 @@ AO_test_and_set_full(volatile AO_TS_t *addr)
 AO_INLINE int
 AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val)
 {
-# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+# ifdef AO_USE_SYNC_CAS_BUILTIN
     return (int)__sync_bool_compare_and_swap(addr, old, new_val);
 # else
     char result;