From 101389e4df4a9661d22d9e9e7e15a7284ef06d0d Mon Sep 17 00:00:00 2001 From: Michael Jeanson Date: Tue, 7 Dec 2021 14:42:26 -0500 Subject: [PATCH] fix: properly detect 'cmpxchg' on x86-32 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 Signed-off-by: Mathieu Desnoyers --- include/urcu/arch.h | 20 +++++++++++++++----- include/urcu/uatomic/x86.h | 2 +- src/compat_arch.c | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/include/urcu/arch.h b/include/urcu/arch.h index 620743c..2bffdbe 100644 --- a/include/urcu/arch.h +++ b/include/urcu/arch.h @@ -64,15 +64,25 @@ #define URCU_ARCH_AMD64 1 #include -#elif (defined(__i486__) || defined(__i586__) || defined(__i686__)) +#elif (defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i586__) || defined(__i686__)) #define URCU_ARCH_X86 1 -#include - -#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 #elif (defined(__powerpc64__) || defined(__ppc64__)) diff --git a/include/urcu/uatomic/x86.h b/include/urcu/uatomic/x86.h index f4e1887..d416963 100644 --- a/include/urcu/uatomic/x86.h +++ b/include/urcu/uatomic/x86.h @@ -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 diff --git a/src/compat_arch.c b/src/compat_arch.c index e1651d3..50bdffb 100644 --- a/src/compat_arch.c +++ b/src/compat_arch.c @@ -22,7 +22,7 @@ #include -#if defined(URCU_ARCH_I386) +#ifdef URCU_ARCH_X86_NO_CAS #include #include -- 2.34.1