fix: properly detect 'cmpxchg' on x86-32
authorMichael Jeanson <mjeanson@efficios.com>
Tue, 7 Dec 2021 19:42:26 +0000 (14:42 -0500)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Thu, 9 Dec 2021 17:18:00 +0000 (12:18 -0500)
We wrongly assumed that on x86-32 when '__i386__' is defined but none of
'__i486__', '__i586__' or '__i686__' that the target arch is a literal
i386 cpu without the cmpxchg instructions. However, when building with
'-march=core2' we get '__i386__' but none of the others even if the arch
is newer than an i686.

Change the compat code to use the '__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4'
builtin define to detect an x86-32 system without the cmpxchg
instructions.

Since this builtin define was introduced in GCC 4.3 and Clang 3.3,
building with older compilers on any x86-32 system will enable the
compat layer regardless of the availability of the instructions.

Change-Id: I8329431e55d778405b2ca7007d90c2c6e5cdd426
Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
include/urcu/arch.h
include/urcu/uatomic/x86.h
src/compat_arch.c

index 620743c0f68fb33dd004d3266bcf900e2a96b898..2bffdbe97d8e20339d1d06ea6ccb66e79b4d366c 100644 (file)
 #define URCU_ARCH_AMD64 1
 #include <urcu/arch/x86.h>
 
-#elif (defined(__i486__) || defined(__i586__) || defined(__i686__))
+#elif (defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i586__) || defined(__i686__))
 
 #define URCU_ARCH_X86 1
-#include <urcu/arch/x86.h>
-
-#elif (defined(__i386__) || defined(__i386))
 
-#define URCU_ARCH_X86 1
+/*
+ * URCU_ARCH_X86_NO_CAS enables a compat layer that will detect the presence of
+ * the cmpxchg instructions at runtime and provide a compat mode based on a
+ * pthread mutex when it isn't.
+ *
+ * __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 was introduced in GCC 4.3 and Clang 3.3,
+ * building with older compilers will result in the compat layer always being
+ * used on x86-32.
+ */
+#ifndef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
+#define URCU_ARCH_X86_NO_CAS 1
+/* For backwards compat */
 #define URCU_ARCH_I386 1
+#endif
+
 #include <urcu/arch/x86.h>
 
 #elif (defined(__powerpc64__) || defined(__ppc64__))
index f4e1887477684f779edd2d865ad3e7edb86eee37..d416963c31aeca0cdd5003b67858c1209779627c 100644 (file)
@@ -529,7 +529,7 @@ void __uatomic_dec(void *addr, int len)
 
 #define _uatomic_dec(addr)     (__uatomic_dec((addr), sizeof(*(addr))))
 
-#if ((CAA_BITS_PER_LONG != 64) && defined(URCU_ARCH_I386))
+#ifdef URCU_ARCH_X86_NO_CAS
 
 /* For backwards compat */
 #define CONFIG_RCU_COMPAT_ARCH 1
index e1651d3db9a2110ae18702c85dc4b7f1cb574838..50bdffbe4935ad4d595b40f3a774ea1c087fc21d 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <urcu/arch.h>
 
-#if defined(URCU_ARCH_I386)
+#ifdef URCU_ARCH_X86_NO_CAS
 
 #include <stdio.h>
 #include <pthread.h>
This page took 0.02754 seconds and 4 git commands to generate.