1
1

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>
Этот коммит содержится в:
Nathan Hjelm 2016-06-02 15:29:19 -06:00
родитель bfcf145613
Коммит d86e41ea13
2 изменённых файлов: 25 добавлений и 3 удалений

Просмотреть файл

@ -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__)