+2010-02-18 Ivan Maidanski <ivmai@mail.ru>
+
+ * src/atomic_ops/sysdeps/gcc/x86_64.h (AO_nop_full): Don't check
+ for AO_USE_PENTIUM4_INSTRS (since "mfence" (SSE2) is supported on
+ all x86_64/amd64 chips); remove the comment.
+ * src/atomic_ops/sysdeps/msftc/x86_64.h (AO_nop_full): Ditto.
+ * src/atomic_ops/sysdeps/msftc/x86_64.h (AO_nop_full): Define only
+ if AO_ASM_X64_AVAILABLE.
+ * src/atomic_ops/sysdeps/gcc/x86_64.h (AO_compare_and_swap_full):
+ Use built-in __sync_bool_compare_and_swap() if GCC v4.2+.
+
2010-02-17 Ivan Maidanski <ivmai@mail.ru> (really Patrick Marlier)
* src/atomic_ops/sysdeps/gcc/x86.h (AO_compare_and_swap_full,
#include "../standard_ao_double_t.h"
-#if defined(AO_USE_PENTIUM4_INSTRS)
AO_INLINE void
AO_nop_full(void)
{
+ /* Note: "mfence" (SSE2) is supported on all x86_64/amd64 chips. */
__asm__ __volatile__("mfence" : : : "memory");
}
#define AO_HAVE_nop_full
-#else
-
-/* We could use the cpuid instruction. But that seems to be slower */
-/* than the default implementation based on test_and_set_full. Thus */
-/* we omit that bit of misinformation here. */
-
-#endif
-
/* As far as we can tell, the lfence and sfence instructions are not */
/* currently needed or useful for cached memory accesses. */
/* 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; cmpxchgq %3, %0; setz %1"
- : "=m"(*addr), "=a"(result)
- : "m"(*addr), "r" (new_val), "a"(old) : "memory");
- return (int) result;
+# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 2)
+ return (int)__sync_bool_compare_and_swap(addr, old, new_val);
+# else
+ char result;
+ __asm__ __volatile__("lock; cmpxchgq %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
/* As far as we can tell, the lfence and sfence instructions are not */
/* currently needed or useful for cached memory accesses. */
-/* Unfortunately mfence doesn't exist everywhere. */
-/* IsProcessorFeaturePresent(PF_COMPARE_EXCHANGE128) is */
-/* probably a conservative test for it? */
-
-#if defined(AO_USE_PENTIUM4_INSTRS)
+#ifdef AO_ASM_X64_AVAILABLE
AO_INLINE void
AO_nop_full(void)
{
+ /* Note: "mfence" (SSE2) is supported on all x86_64/amd64 chips. */
__asm { mfence }
}
#define AO_HAVE_nop_full
-#else
-
-/* We could use the cpuid instruction. But that seems to be slower */
-/* than the default implementation based on test_and_set_full. Thus */
-/* we omit that bit of misinformation here. */
-
-#endif
-
-#ifdef AO_ASM_X64_AVAILABLE
-
AO_INLINE AO_TS_VAL_t
AO_test_and_set_full(volatile AO_TS_t *addr)
{