From 15248032ea9e3e88849310e8f2cef9db618fce1a Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Mon, 15 Jul 2013 14:13:53 -0700 Subject: [PATCH] configure: Add configure-time check for GCC 4.0+ atomic built-ins. We found out earlier that GCC sometimes produces an error only at link time for atomic built-ins that are not supported on a platform. This actually tries the link at configure time and should thus reliably detect whether the atomic built-ins are really supported. Signed-off-by: Ben Pfaff Acked-by: Ethan Jackson --- configure.ac | 1 + lib/ovs-atomic.h | 2 +- m4/openvswitch.m4 | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 70fc9df25..89541aaef 100644 --- a/configure.ac +++ b/configure.ac @@ -83,6 +83,7 @@ OVS_CHECK_GROFF OVS_CHECK_GNU_MAKE OVS_CHECK_CACHE_TIME OVS_CHECK_TLS +OVS_CHECK_GCC4_ATOMICS OVS_CHECK_ATOMIC_ALWAYS_LOCK_FREE(1) OVS_CHECK_ATOMIC_ALWAYS_LOCK_FREE(2) OVS_CHECK_ATOMIC_ALWAYS_LOCK_FREE(4) diff --git a/lib/ovs-atomic.h b/lib/ovs-atomic.h index a0a34f30f..3fc9dcb8f 100644 --- a/lib/ovs-atomic.h +++ b/lib/ovs-atomic.h @@ -240,7 +240,7 @@ #include "ovs-atomic-c11.h" #elif __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #include "ovs-atomic-gcc4.7+.h" - #elif __GNUC__ >= 4 + #elif HAVE_GCC4_ATOMICS #include "ovs-atomic-gcc4+.h" #else #include "ovs-atomic-pthreads.h" diff --git a/m4/openvswitch.m4 b/m4/openvswitch.m4 index dbfc7c425..bcdb942b9 100644 --- a/m4/openvswitch.m4 +++ b/m4/openvswitch.m4 @@ -426,6 +426,78 @@ static thread_local int var;], [return var;])], fi fi]) +dnl OVS_CHECK_GCC4_ATOMICS +dnl +dnl Checks whether the compiler and linker support GCC 4.0+ atomic built-ins. +dnl A compile-time only check is not enough because the compiler defers +dnl unimplemented built-ins to libgcc, which sometimes also lacks +dnl implementations. +AC_DEFUN([OVS_CHECK_GCC4_ATOMICS], + [AC_CACHE_CHECK( + [whether $CC supports GCC 4.0+ atomic built-ins], + [ovs_cv_gcc4_atomics], + [AC_LINK_IFELSE( + [AC_LANG_PROGRAM([[#include + +#define ovs_assert(expr) if (!(expr)) abort(); +#define TEST_ATOMIC_TYPE(TYPE) \ + { \ + TYPE x = 1; \ + TYPE orig; \ + \ + __sync_synchronize(); \ + ovs_assert(x == 1); \ + \ + __sync_synchronize(); \ + x = 3; \ + __sync_synchronize(); \ + ovs_assert(x == 3); \ + \ + orig = __sync_fetch_and_add(&x, 1); \ + ovs_assert(orig == 3); \ + __sync_synchronize(); \ + ovs_assert(x == 4); \ + \ + orig = __sync_fetch_and_sub(&x, 2); \ + ovs_assert(orig == 4); \ + __sync_synchronize(); \ + ovs_assert(x == 2); \ + \ + orig = __sync_fetch_and_or(&x, 6); \ + ovs_assert(orig == 2); \ + __sync_synchronize(); \ + ovs_assert(x == 6); \ + \ + orig = __sync_fetch_and_and(&x, 10); \ + ovs_assert(orig == 6); \ + __sync_synchronize(); \ + ovs_assert(x == 2); \ + \ + orig = __sync_fetch_and_xor(&x, 10); \ + ovs_assert(orig == 2); \ + __sync_synchronize(); \ + ovs_assert(x == 8); \ + }]], [dnl +TEST_ATOMIC_TYPE(char); +TEST_ATOMIC_TYPE(unsigned char); +TEST_ATOMIC_TYPE(signed char); +TEST_ATOMIC_TYPE(short); +TEST_ATOMIC_TYPE(unsigned short); +TEST_ATOMIC_TYPE(int); +TEST_ATOMIC_TYPE(unsigned int); +TEST_ATOMIC_TYPE(long int); +TEST_ATOMIC_TYPE(unsigned long int); +TEST_ATOMIC_TYPE(long long int); +TEST_ATOMIC_TYPE(unsigned long long int); +])], + [ovs_cv_gcc4_atomics=yes], + [ovs_cv_gcc4_atomics=no])]) + if test $ovs_cv_gcc4_atomics = yes; then + AC_DEFINE([HAVE_GCC4_ATOMICS], [1], + [Define to 1 if the C compiler and linker supports the GCC 4.0+ + atomic built-ins.]) + fi]) + dnl OVS_CHECK_ATOMIC_ALWAYS_LOCK_FREE(SIZE) dnl dnl Checks __atomic_always_lock_free(SIZE, 0) -- 2.43.0