Skip to content

Commit bc8617c

Browse files
committed
opal/atomic: always use C11 atomics if available
This commit disables the use of both the builtin and hand-written atomics if proper C11 atomic support is detected. This is the first step towards requiring the availability of C11 atomics for the C compiler used to build Open MPI. Signed-off-by: Nathan Hjelm <[email protected]>
1 parent b7e7bb4 commit bc8617c

File tree

13 files changed

+386
-25
lines changed

13 files changed

+386
-25
lines changed

config/opal_config_asm.m4

+63-9
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,50 @@ dnl $HEADER$
2525
dnl
2626

2727

28+
AC_DEFUN([OPAL_CHECK_C11_CSWAP_INT128], [
29+
30+
OPAL_VAR_SCOPE_PUSH([c11_compare_and_swap_128_result c11_CFLAGS_save])
31+
32+
AC_ARG_ENABLE([cross-cmpset128],[AC_HELP_STRING([--enable-cross-cmpset128],
33+
[enable the use of the C11 atomic compare-and-swap 128 when cross compiling])])
34+
35+
c11_compare_and_swap_128_result=0
36+
37+
# This test specifically DOES NOT use -latomic because we do not want a lock-based atomic
38+
for flag in "" "-mcx16" ; do
39+
c11_CFLAGS_save=$CFLAGS
40+
if test "x$flag" != "x" ; then
41+
AC_MSG_CHECKING([for compiler support for C11 atomic compare-and-swap on 128-bit values with flag $flag])
42+
CFLAGS="$CFLAGS $flag"
43+
else
44+
AC_MSG_CHECKING([for compiler support for C11 atomic compare-and-swap on 128-bit values])
45+
fi
46+
47+
if test ! "$enable_cross_cmpset128" = "yes" ; then
48+
AC_RUN_IFELSE([AC_LANG_PROGRAM([#include <stdatomic.h>], [__int128 x = 0; atomic_compare_exchange_strong (&x, &(__int128){0}, 1); return !atomic_is_lock_free(&x);])],
49+
[AC_MSG_RESULT([yes]); c11_compare_and_swap_128_result=1; break],
50+
[AC_MSG_RESULT([no])], [AC_MSG_RESULT([no (cross compiling)])])
51+
else
52+
AC_LINK_IFELSE([AC_LANG_PROGRAM([#include <stdatomic.h>], [__int128 x = 0; atomic_compare_exchange_strong (&x, &(__int128){0}, 1);])],
53+
[AC_MSG_RESULT([yes]); c11_compare_and_swap_128_result=1; break],
54+
[AC_MSG_RESULT([no])])
55+
fi
56+
57+
CFLAGS=$c11_CFLAGS_save
58+
done
59+
60+
AC_DEFINE_UNQUOTED([OPAL_HAVE_C11_CSWAP_INT128], [$c11_compare_and_swap_128_result],
61+
[Whether the compiler support C11 atomic compare and swap supports 128-bit values])
62+
63+
# For x86_64 systems it is impossible to get cmpxchng16b to be used do to slow reads of atomic variables. In Open MPI
64+
# we are careful to read these values in consistent way so use __sync instead.
65+
if test $c11_compare_and_swap_128_result = 0 ; then
66+
OPAL_CHECK_SYNC_BUILTIN_CSWAP_INT128
67+
fi
68+
69+
OPAL_VAR_SCOPE_POP
70+
])
71+
2872
AC_DEFUN([OPAL_CHECK_SYNC_BUILTIN_CSWAP_INT128], [
2973
3074
OPAL_VAR_SCOPE_PUSH([sync_bool_compare_and_swap_128_result CFLAGS_save])
@@ -911,17 +955,27 @@ AC_DEFUN([OPAL_CONFIG_ASM],[
911955
AC_REQUIRE([OPAL_SETUP_CC])
912956
AC_REQUIRE([AM_PROG_AS])
913957
958+
AC_ARG_ENABLE([c11-atomics],[AC_HELP_STRING([--enable-c11-atomics],
959+
[Enable use of C11 atomics if available (default: enabled)])])
960+
914961
AC_ARG_ENABLE([builtin-atomics],
915962
[AC_HELP_STRING([--enable-builtin-atomics],
916-
[Enable use of __sync builtin atomics (default: enabled)])])
917-
918-
opal_cv_asm_builtin="BUILTIN_NO"
919-
AS_IF([test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" != "no"],
920-
[OPAL_CHECK_GCC_ATOMIC_BUILTINS([opal_cv_asm_builtin="BUILTIN_GCC"], [])])
921-
AS_IF([test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" != "no"],
922-
[OPAL_CHECK_SYNC_BUILTINS([opal_cv_asm_builtin="BUILTIN_SYNC"], [])])
923-
AS_IF([test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes"],
924-
[AC_MSG_ERROR([__sync builtin atomics requested but not found.])])
963+
[Enable use of __sync builtin atomics (default: disabled)])])
964+
965+
OPAL_CHECK_C11_CSWAP_INT128
966+
967+
if test "x$enable_c11_atomics" != "no" && test "$opal_cv_c11_supported" = "yes" ; then
968+
opal_cv_asm_builtin="BUILTIN_C11"
969+
OPAL_CHECK_C11_CSWAP_INT128
970+
else
971+
opal_cv_asm_builtin="BUILTIN_NO"
972+
AS_IF([test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes"],
973+
[OPAL_CHECK_GCC_ATOMIC_BUILTINS([opal_cv_asm_builtin="BUILTIN_GCC"], [])])
974+
AS_IF([test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes"],
975+
[OPAL_CHECK_SYNC_BUILTINS([opal_cv_asm_builtin="BUILTIN_SYNC"], [])])
976+
AS_IF([test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes"],
977+
[AC_MSG_ERROR([__sync builtin atomics requested but not found.])])
978+
fi
925979
926980
OPAL_CHECK_ASM_PROC
927981
OPAL_CHECK_ASM_TEXT

opal/class/opal_fifo.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -155,11 +155,9 @@ static inline opal_list_item_t *opal_fifo_pop_atomic (opal_fifo_t *fifo)
155155
* update the head */
156156

157157
/* wait for next pointer to be updated by push */
158-
while (ghost == item->opal_list_next) {
158+
do {
159159
opal_atomic_rmb ();
160-
}
161-
162-
opal_atomic_rmb ();
160+
} while (ghost == item->opal_list_next);
163161

164162
/* update the head with the real next value. note that no other thread
165163
* will be attempting to update the head until after it has been updated

opal/class/opal_object.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ int opal_class_init_epoch = 1;
5555
/*
5656
* Local variables
5757
*/
58-
static opal_atomic_lock_t class_lock = { { OPAL_ATOMIC_LOCK_UNLOCKED } };
58+
static opal_atomic_lock_t class_lock = OPAL_ATOMIC_LOCK_INIT;
5959
static void** classes = NULL;
6060
static int num_classes = 0;
6161
static int max_classes = 0;

opal/include/opal/sys/Makefile.am

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
# All rights reserved.
1212
# Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
1313
# Copyright (c) 2011 Sandia National Laboratories. All rights reserved.
14-
# Copyright (c) 2016 Los Alamos National Security, LLC. All rights
14+
# Copyright (c) 2016-2018 Los Alamos National Security, LLC. All rights
1515
# reserved.
1616
# Copyright (c) 2017 Research Organization for Information Science
1717
# and Technology (RIST). All rights reserved.
@@ -27,6 +27,7 @@
2727
headers += \
2828
opal/sys/architecture.h \
2929
opal/sys/atomic.h \
30+
opal/sys/atomic_stdc.h \
3031
opal/sys/atomic_impl.h \
3132
opal/sys/timer.h \
3233
opal/sys/cma.h

opal/include/opal/sys/architecture.h

+1
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@
4747
#define OPAL_BUILTIN_SYNC 0200
4848
#define OPAL_BUILTIN_GCC 0202
4949
#define OPAL_BUILTIN_NO 0203
50+
#define OPAL_BUILTIN_C11 0204
5051

5152
/* Formats */
5253
#define OPAL_DEFAULT 1000 /* standard for given architecture */

opal/include/opal/sys/atomic.h

+10
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,12 @@
5858
#include "opal/sys/architecture.h"
5959
#include "opal_stdatomic.h"
6060

61+
#if OPAL_ASSEMBLY_BUILTIN == OPAL_BUILTIN_C11
62+
63+
#include "atomic_stdc.h"
64+
65+
#else /* !OPAL_C_HAVE__ATOMIC */
66+
6167
/* do some quick #define cleanup in cases where we are doing
6268
testing... */
6369
#ifdef OPAL_DISABLE_INLINE_ASM
@@ -147,6 +153,8 @@ enum {
147153
OPAL_ATOMIC_LOCK_LOCKED = 1
148154
};
149155

156+
#define OPAL_ATOMIC_LOCK_INIT {.u = {.lock = OPAL_ATOMIC_LOCK_UNLOCKED}}
157+
150158
/**********************************************************************
151159
*
152160
* Load the appropriate architecture files and set some reasonable
@@ -643,6 +651,8 @@ static inline intptr_t opal_atomic_fetch_sub_ptr( opal_atomic_intptr_t* addr, vo
643651
*/
644652
#include "opal/sys/atomic_impl.h"
645653

654+
#endif /* !OPAL_C_HAVE__ATOMIC */
655+
646656
END_C_DECLS
647657

648658
#endif /* OPAL_SYS_ATOMIC_H */

0 commit comments

Comments
 (0)