@@ -13,7 +13,7 @@ dnl Copyright (c) 2008-2018 Cisco Systems, Inc. All rights reserved.
13
13
dnl Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved.
14
14
dnl Copyright (c) 2015-2017 Research Organization for Information Science
15
15
dnl and Technology (RIST). All rights reserved.
16
- dnl Copyright (c) 2014-2017 Los Alamos National Security, LLC. All rights
16
+ dnl Copyright (c) 2014-2018 Los Alamos National Security, LLC. All rights
17
17
dnl reserved.
18
18
dnl Copyright (c) 2017 Amazon.com, Inc. or its affiliates. All Rights
19
19
dnl reserved.
@@ -122,6 +122,58 @@ int main(int argc, char** argv)
122
122
}
123
123
] ] )
124
124
125
+ dnl This is a C test to see if 128-bit __atomic_compare_exchange_n()
126
+ dnl actually works (e.g., it compiles and links successfully on
127
+ dnl ARM64+clang, but returns incorrect answers as of August 2018).
128
+ AC_DEFUN ( [ OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_TEST_SOURCE] ,[ [
129
+ #include <stdint.h>
130
+ #include <stdbool.h>
131
+ #include <stdlib.h>
132
+ #include <stdatomic.h>
133
+
134
+ typedef union {
135
+ uint64_t fake@<:@ 2@:>@ ;
136
+ _Atomic __int128 real;
137
+ } ompi128;
138
+
139
+ static void test1(void)
140
+ {
141
+ // As of Aug 2018, we could not figure out a way to assign 128-bit
142
+ // constants -- the compilers would not accept it. So use a fake
143
+ // union to assign 2 uin64_t's to make a single __int128.
144
+ ompi128 ptr = { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
145
+ ompi128 expected = { .fake = { 0x11EEDDCCBBAA0099, 0x88776655443322FF }};
146
+ ompi128 desired = { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
147
+ bool r = atomic_compare_exchange_strong (&ptr.real, &expected.real,
148
+ desired.real, true,
149
+ atomic_relaxed, atomic_relaxed);
150
+ if ( !(r == false && ptr.real == expected.real)) {
151
+ exit(1);
152
+ }
153
+ }
154
+
155
+ static void test2(void)
156
+ {
157
+ ompi128 ptr = { .fake = { 0xFFEEDDCCBBAA0099, 0x8877665544332211 }};
158
+ ompi128 expected = ptr;
159
+ ompi128 desired = { .fake = { 0x1122DDCCBBAA0099, 0x887766554433EEFF }};
160
+ bool r = atomic_compare_exchange_strong (&ptr.real, &expected.real,
161
+ desired.real, true,
162
+ atomic_relaxed, atomic_relaxed);
163
+ if (!(r == true && ptr.real == desired.real)) {
164
+ exit(2);
165
+ }
166
+ }
167
+
168
+ vvvvvvvvvvvvvvvvvvvv
169
+ int main(int argc, char** argv)
170
+ {
171
+ test1();
172
+ test2();
173
+ return 0;
174
+ }
175
+ ] ] )
176
+
125
177
dnl ------------------------------------------------------------------
126
178
127
179
dnl
@@ -329,6 +381,71 @@ __atomic_add_fetch(&tmp64, 1, __ATOMIC_RELAXED);],
329
381
OPAL_CHECK_GCC_BUILTIN_CSWAP_INT128
330
382
] )
331
383
384
+ AC_DEFUN ( [ OPAL_CHECK_C11_CSWAP_INT128] , [
385
+ OPAL_VAR_SCOPE_PUSH([ atomic_compare_exchange_result atomic_compare_exchange_CFLAGS_save atomic_compare_exchange_LIBS_save] )
386
+
387
+ atomic_compare_exchange_CFLAGS_save=$CFLAGS
388
+ atomic_compare_exchange_LIBS_save=$LIBS
389
+
390
+ # Do we have C11 atomics on 128-bit integers?
391
+ # Use a special macro because we need to check with a few different
392
+ # CFLAGS/LIBS.
393
+ OPAL_ASM_CHECK_ATOMIC_FUNC([ atomic_compare_exchange_strong_16] ,
394
+ [ AC_LANG_SOURCE ( OPAL_ATOMIC_COMPARE_EXCHANGE_STRONG_TEST_SOURCE ) ] ,
395
+ [ atomic_compare_exchange_result=1] ,
396
+ [ atomic_compare_exchange_result=0] )
397
+
398
+ # If we have it and it works, check to make sure it is always lock
399
+ # free.
400
+ AS_IF ( [ test $atomic_compare_exchange_result -eq 1] ,
401
+ [ AC_MSG_CHECKING ( [ if C11 __int128 atomic compare-and-swap is always lock-free] )
402
+ AC_RUN_IFELSE ( [ AC_LANG_PROGRAM ( [ #include <stdatomic.h>] , [ _Atomic __int128_t x; if (!atomic_is_lock_free(&x)) { return 1; }] ) ] ,
403
+ [ AC_MSG_RESULT ( [ yes] ) ] ,
404
+ [ atomic_compare_exchange_result=0
405
+ # If this test fails, need to reset CFLAGS/LIBS (the
406
+ # above tests atomically set CFLAGS/LIBS or not; this
407
+ # test is running after the fact, so we have to undo
408
+ # the side-effects of setting CFLAGS/LIBS if the above
409
+ # tests passed).
410
+ CFLAGS=$atomic_compare_exchange_CFLAGS_save
411
+ LIBS=$atomic_compare_exchange_LIBS_save
412
+ AC_MSG_RESULT ( [ no] ) ] ,
413
+ [ AC_MSG_RESULT ( [ cannot test -- assume yes (cross compiling)] ) ] )
414
+ ] )
415
+
416
+ AC_DEFINE_UNQUOTED ( [ OPAL_HAVE_C11_CSWAP_INT128] ,
417
+ [ $atomic_compare_exchange_result] ,
418
+ [ Whether C11 atomic compare swap is both supported and lock-free on 128-bit values] )
419
+
420
+ dnl If we could not find decent support for 128-bits atomic let's
421
+ dnl try the GCC _sync
422
+ AS_IF ( [ test $atomic_compare_exchange_result -eq 0] ,
423
+ [ OPAL_CHECK_SYNC_BUILTIN_CSWAP_INT128] )
424
+
425
+ OPAL_VAR_SCOPE_POP
426
+ ] )
427
+
428
+ AC_DEFUN ( [ OPAL_CHECK_GCC_ATOMIC_BUILTINS] , [
429
+ AC_MSG_CHECKING ( [ for __atomic builtin atomics] )
430
+
431
+ AC_TRY_LINK ( [
432
+ #include <stdint.h>
433
+ uint32_t tmp, old = 0;
434
+ uint64_t tmp64, old64 = 0;] , [
435
+ __atomic_thread_fence(__ATOMIC_SEQ_CST);
436
+ __atomic_compare_exchange_n(&tmp, &old, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
437
+ __atomic_add_fetch(&tmp, 1, __ATOMIC_RELAXED);
438
+ __atomic_compare_exchange_n(&tmp64, &old64, 1, 0, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
439
+ __atomic_add_fetch(&tmp64, 1, __ATOMIC_RELAXED);] ,
440
+ [ AC_MSG_RESULT ( [ yes] )
441
+ $1 ] ,
442
+ [ AC_MSG_RESULT ( [ no] )
443
+ $2 ] )
444
+
445
+ # Check for 128-bit support
446
+ OPAL_CHECK_GCC_BUILTIN_CSWAP_INT128
447
+ ] )
448
+
332
449
333
450
dnl #################################################################
334
451
dnl
@@ -1020,17 +1137,27 @@ AC_DEFUN([OPAL_CONFIG_ASM],[
1020
1137
AC_REQUIRE ( [ OPAL_SETUP_CC] )
1021
1138
AC_REQUIRE ( [ AM_PROG_AS ] )
1022
1139
1140
+ AC_ARG_ENABLE ( [ c11-atomics] ,[ AC_HELP_STRING ([ --enable-c11-atomics] ,
1141
+ [ Enable use of C11 atomics if available (default: enabled)] )] )
1142
+
1023
1143
AC_ARG_ENABLE ( [ builtin-atomics] ,
1024
1144
[ AC_HELP_STRING ([ --enable-builtin-atomics] ,
1025
- [ Enable use of __sync builtin atomics (default: enabled)] )] )
1026
-
1027
- opal_cv_asm_builtin="BUILTIN_NO"
1028
- AS_IF ( [ test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" != "no"] ,
1029
- [ OPAL_CHECK_GCC_ATOMIC_BUILTINS([ opal_cv_asm_builtin="BUILTIN_GCC"] , [ ] )] )
1030
- AS_IF ( [ test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" != "no"] ,
1031
- [ OPAL_CHECK_SYNC_BUILTINS([ opal_cv_asm_builtin="BUILTIN_SYNC"] , [ ] )] )
1032
- AS_IF ( [ test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes"] ,
1033
- [ AC_MSG_ERROR ( [ __sync builtin atomics requested but not found.] ) ] )
1145
+ [ Enable use of __sync builtin atomics (default: disabled)] )] )
1146
+
1147
+ OPAL_CHECK_C11_CSWAP_INT128
1148
+
1149
+ if test "x$enable_c11_atomics" != "xno" && test "$opal_cv_c11_supported" = "yes" ; then
1150
+ opal_cv_asm_builtin="BUILTIN_C11"
1151
+ OPAL_CHECK_C11_CSWAP_INT128
1152
+ else
1153
+ opal_cv_asm_builtin="BUILTIN_NO"
1154
+ AS_IF ( [ test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes"] ,
1155
+ [ OPAL_CHECK_GCC_ATOMIC_BUILTINS([ opal_cv_asm_builtin="BUILTIN_GCC"] , [ ] )] )
1156
+ AS_IF ( [ test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes"] ,
1157
+ [ OPAL_CHECK_SYNC_BUILTINS([ opal_cv_asm_builtin="BUILTIN_SYNC"] , [ ] )] )
1158
+ AS_IF ( [ test "$opal_cv_asm_builtin" = "BUILTIN_NO" && test "$enable_builtin_atomics" = "yes"] ,
1159
+ [ AC_MSG_ERROR ( [ __sync builtin atomics requested but not found.] ) ] )
1160
+ fi
1034
1161
1035
1162
OPAL_CHECK_ASM_PROC
1036
1163
OPAL_CHECK_ASM_TEXT
0 commit comments