atomic/gcc: add check for 128-bit CAS being lock-free
Compiler implementations are free to include support for atomics that use locks. Unfortunately lock-free and lock atomics do not mix. Older versions of llvm on OS X use locks to provide __atomic_compare_exchange on 128-bit values but are lock-free on 64-bit values. This screws up our lifo implementation which mixes 64-bit and 128-bit atomics on the same values to improve performance. This commit adds a configure-time check if 128-bit atomics are lock free. If they are not then the 128-bit __atomic CAS is disabled and we check for the __sync version as a fallback. Signed-off-by: Nathan Hjelm <hjelmn@lanl.gov>
Этот коммит содержится в:
родитель
bfcf145613
Коммит
d86e41ea13
@ -148,11 +148,21 @@ AC_DEFUN([OPAL_CHECK_GCC_BUILTIN_CSWAP_INT128], [
|
||||
|
||||
CFLAGS=$CFLAGS_save
|
||||
fi
|
||||
|
||||
if test $atomic_compare_exchange_n_128_result = 1 ; then
|
||||
AC_MSG_CHECKING([if __int128 atomic compare-and-swap is always lock-free])
|
||||
AC_RUN_IFELSE([AC_LANG_PROGRAM([], [if (!__atomic_always_lock_free(16, 0)) { return 1; }])],
|
||||
[AC_MSG_RESULT([yes])],
|
||||
[AC_MSG_RESULT([no])
|
||||
OPAL_CHECK_SYNC_BUILTIN_CSWAP_INT128
|
||||
atomic_compare_exchange_n_128_result=0],
|
||||
[AC_MSG_RESULT([no (cross compiling)])])
|
||||
fi
|
||||
else
|
||||
AC_MSG_CHECKING([for compiler support of __atomic builtin atomic compare-and-swap on 128-bit values])
|
||||
|
||||
# Check if the compiler supports the __atomic builtin
|
||||
AC_TRY_LINK([], [__int128 x = 0; __atomic_bool_compare_and_swap (&x, 0, 1);],
|
||||
AC_TRY_LINK([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);],
|
||||
[AC_MSG_RESULT([yes])
|
||||
atomic_compare_exchange_n_128_result=1],
|
||||
[AC_MSG_RESULT([no])])
|
||||
@ -162,7 +172,7 @@ AC_DEFUN([OPAL_CHECK_GCC_BUILTIN_CSWAP_INT128], [
|
||||
CFLAGS="$CFLAGS -mcx16"
|
||||
|
||||
AC_MSG_CHECKING([for __atomic builtin atomic compare-and-swap on 128-bit values with -mcx16 flag])
|
||||
AC_TRY_LINK([], [__int128 x = 0; __atomic_bool_compare_and_swap (&x, 0, 1);],
|
||||
AC_TRY_LINK([], [__int128 x = 0, y = 0; __atomic_compare_exchange_n (&x, &y, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);],
|
||||
[AC_MSG_RESULT([yes])
|
||||
atomic_compare_exchange_n_128_result=1
|
||||
CFLAGS_save="$CFLAGS"],
|
||||
@ -173,7 +183,7 @@ AC_DEFUN([OPAL_CHECK_GCC_BUILTIN_CSWAP_INT128], [
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED([OPAL_HAVE_GCC_BUILTIN_CSWAP_INT128], [$atomic_compare_exchange_n_128_result],
|
||||
[Whether the __atomic builtin atomic compare and swap supports 128-bit values])
|
||||
[Whether the __atomic builtin atomic compare and swap is lock-free on 128-bit values])
|
||||
|
||||
OPAL_VAR_SCOPE_POP
|
||||
])
|
||||
|
@ -156,6 +156,18 @@ static inline int opal_atomic_cmpset_128 (volatile opal_int128_t *addr,
|
||||
__ATOMIC_ACQUIRE, __ATOMIC_RELAXED);
|
||||
}
|
||||
|
||||
#elif defined(OPAL_HAVE_SYNC_BUILTIN_CSWAP_INT128) && OPAL_HAVE_SYNC_BUILTIN_CSWAP_INT128
|
||||
|
||||
#define OPAL_HAVE_ATOMIC_CMPSET_128 1
|
||||
|
||||
/* __atomic version is not lock-free so use legacy __sync version */
|
||||
|
||||
static inline int opal_atomic_cmpset_128 (volatile opal_int128_t *addr,
|
||||
opal_int128_t oldval, opal_int128_t newval)
|
||||
{
|
||||
return __sync_bool_compare_and_swap (addr, oldval, newval);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(__HLE__)
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user