Skip to content

Commit

Permalink
configure: Add configure-time check for GCC 4.0+ atomic built-ins.
Browse files Browse the repository at this point in the history
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 <[email protected]>
Acked-by: Ethan Jackson <[email protected]>
  • Loading branch information
blp committed Jul 31, 2013
1 parent 97be153 commit 1524803
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 1 deletion.
1 change: 1 addition & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion lib/ovs-atomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
72 changes: 72 additions & 0 deletions m4/openvswitch.m4
Original file line number Diff line number Diff line change
Expand Up @@ -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 <stdlib.h>
#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)
Expand Down

0 comments on commit 1524803

Please sign in to comment.