Skip to content

Commit 72a85a9

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 4476b11 commit 72a85a9

File tree

9 files changed

+295
-11
lines changed

9 files changed

+295
-11
lines changed

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/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_C_HAVE__ATOMIC
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 */

opal/include/opal/sys/atomic_stdc.h

+240
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,240 @@
1+
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
2+
/*
3+
* Copyright (c) 2018 Los Alamos National Security, LLC. All rights
4+
* reserved.
5+
* $COPYRIGHT$
6+
*
7+
* Additional copyrights may follow
8+
*
9+
* $HEADER$
10+
*/
11+
12+
/* This file provides shims between the opal atomics interface and the C11 atomics interface. It
13+
* is intended as the first step in moving to using C11 atomics across the entire codebase. Once
14+
* all officially supported compilers offer C11 atomic (GCC 4.9.0+, icc 2018+, pgi, xlc, etc) then
15+
* this shim will go away and the codebase will be updated to use C11's atomic support
16+
* directly.
17+
* This shim contains some functions already present in atomic_impl.h because we do not include
18+
* atomic_impl.h when using C11 atomics. It would require alot of #ifdefs to avoid duplicate
19+
* definitions to be worthwhile. */
20+
21+
#if !defined(OPAL_ATOMIC_STDC_H)
22+
#define OPAL_ATOMIC_STDC_H
23+
24+
#include <stdatomic.h>
25+
#include <stdint.h>
26+
#include "opal/include/opal_stdint.h"
27+
28+
#define OPAL_HAVE_ATOMIC_MEM_BARRIER 1
29+
30+
#define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 1
31+
#define OPAL_HAVE_ATOMIC_SWAP_32 1
32+
33+
#define OPAL_HAVE_ATOMIC_MATH_32 1
34+
#define OPAL_HAVE_ATOMIC_ADD_32 1
35+
#define OPAL_HAVE_ATOMIC_AND_32 1
36+
#define OPAL_HAVE_ATOMIC_OR_32 1
37+
#define OPAL_HAVE_ATOMIC_XOR_32 1
38+
#define OPAL_HAVE_ATOMIC_SUB_32 1
39+
40+
#define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64 1
41+
#define OPAL_HAVE_ATOMIC_SWAP_64 1
42+
43+
#define OPAL_HAVE_ATOMIC_MATH_64 1
44+
#define OPAL_HAVE_ATOMIC_ADD_64 1
45+
#define OPAL_HAVE_ATOMIC_AND_64 1
46+
#define OPAL_HAVE_ATOMIC_OR_64 1
47+
#define OPAL_HAVE_ATOMIC_XOR_64 1
48+
#define OPAL_HAVE_ATOMIC_SUB_64 1
49+
50+
#define OPAL_HAVE_ATOMIC_LLSC_32 0
51+
#define OPAL_HAVE_ATOMIC_LLSC_64 0
52+
#define OPAL_HAVE_ATOMIC_LLSC_PTR 0
53+
54+
#define OPAL_HAVE_ATOMIC_MIN_32 1
55+
#define OPAL_HAVE_ATOMIC_MAX_32 1
56+
57+
#define OPAL_HAVE_ATOMIC_MIN_64 1
58+
#define OPAL_HAVE_ATOMIC_MAX_64 1
59+
60+
#define OPAL_HAVE_ATOMIC_SPINLOCKS 1
61+
62+
static inline void opal_atomic_mb (void)
63+
{
64+
atomic_thread_fence (memory_order_seq_cst);
65+
}
66+
67+
static inline void opal_atomic_wmb (void)
68+
{
69+
atomic_thread_fence (memory_order_release);
70+
}
71+
72+
static inline void opal_atomic_rmb (void)
73+
{
74+
atomic_thread_fence (memory_order_acquire);
75+
}
76+
77+
#define opal_atomic_compare_exchange_strong_32 atomic_compare_exchange_strong
78+
#define opal_atomic_compare_exchange_strong_64 atomic_compare_exchange_strong
79+
#define opal_atomic_compare_exchange_strong_ptr atomic_compare_exchange_strong
80+
#define opal_atomic_compare_exchange_strong_acq_32(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_acquire, memory_order_relaxed)
81+
#define opal_atomic_compare_exchange_strong_acq_64(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_acquire, memory_order_relaxed)
82+
#define opal_atomic_compare_exchange_strong_acq_ptr(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_acquire, memory_order_relaxed)
83+
84+
#define opal_atomic_compare_exchange_strong_rel_32(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_release, memory_order_relaxed)
85+
#define opal_atomic_compare_exchange_strong_rel_64(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_release, memory_order_relaxed)
86+
#define opal_atomic_compare_exchange_strong_rel_ptr(addr, compare, value) atomic_compare_exchange_strong_explicit (addr, compare, value, memory_order_release, memory_order_relaxed)
87+
88+
#define opal_atomic_compare_exchange_strong atomic_compare_exchange_strong
89+
#define opal_atomic_compare_exchange_strong_acq(addr, oldval, newval) atomic_compare_exchange_strong_explicit (addr, oldval, newval, memory_order_acquire, memory_order_relaxed)
90+
#define opal_atomic_compare_exchange_strong_rel(addr, oldval, newval) atomic_compare_exchange_strong_explicit (addr, oldval, newval, memory_order_release, memory_order_relaxed)
91+
92+
#define opal_atomic_swap_32 atomic_exchange
93+
#define opal_atomic_swap_64 atomic_exchange
94+
#define opal_atomic_swap_ptr atomic_exchange
95+
96+
#define OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(op, bits, type, operator) \
97+
static inline type opal_atomic_fetch_ ## op ##_## bits (opal_atomic_ ## type *addr, type value) \
98+
{ \
99+
return atomic_fetch_ ## op (addr, value); \
100+
} \
101+
\
102+
static inline type opal_atomic_## op ## _fetch_ ## bits (opal_atomic_ ## type *addr, type value) \
103+
{ \
104+
return atomic_fetch_ ## op (addr, value) operator value; \
105+
}
106+
107+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(add, 32, int32_t, +)
108+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(add, 64, int64_t, +)
109+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(add, size_t, size_t, +)
110+
111+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(sub, 32, int32_t, -)
112+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(sub, 64, int64_t, -)
113+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(sub, size_t, size_t, -)
114+
115+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(or, 32, int32_t, |)
116+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(or, 64, int64_t, |)
117+
118+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(xor, 32, int32_t, ^)
119+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(xor, 64, int64_t, ^)
120+
121+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(and, 32, int32_t, &)
122+
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(and, 64, int64_t, &)
123+
124+
#define opal_atomic_add (void) atomic_fetch_add
125+
126+
static inline int32_t opal_atomic_fetch_min_32 (opal_atomic_int32_t *addr, int32_t value)
127+
{
128+
int32_t old = *addr;
129+
do {
130+
if (old <= value) {
131+
break;
132+
}
133+
} while (!opal_atomic_compare_exchange_strong_32 (addr, &old, value));
134+
135+
return old;
136+
}
137+
138+
static inline int32_t opal_atomic_fetch_max_32 (opal_atomic_int32_t *addr, int32_t value)
139+
{
140+
int32_t old = *addr;
141+
do {
142+
if (old >= value) {
143+
break;
144+
}
145+
} while (!opal_atomic_compare_exchange_strong_32 (addr, &old, value));
146+
147+
return old;
148+
}
149+
150+
static inline int64_t opal_atomic_fetch_min_64 (opal_atomic_int64_t *addr, int64_t value)
151+
{
152+
int64_t old = *addr;
153+
do {
154+
if (old <= value) {
155+
break;
156+
}
157+
} while (!opal_atomic_compare_exchange_strong_64 (addr, &old, value));
158+
159+
return old;
160+
}
161+
162+
static inline int64_t opal_atomic_fetch_max_64 (opal_atomic_int64_t *addr, int64_t value)
163+
{
164+
int64_t old = *addr;
165+
do {
166+
if (old >= value) {
167+
break;
168+
}
169+
} while (!opal_atomic_compare_exchange_strong_64 (addr, &old, value));
170+
171+
return old;
172+
}
173+
174+
static inline int32_t opal_atomic_min_fetch_32 (opal_atomic_int32_t *addr, int32_t value)
175+
{
176+
int32_t old = opal_atomic_fetch_min_32 (addr, value);
177+
return old <= value ? old : value;
178+
}
179+
180+
static inline int32_t opal_atomic_max_fetch_32 (opal_atomic_int32_t *addr, int32_t value)
181+
{
182+
int32_t old = opal_atomic_fetch_max_32 (addr, value);
183+
return old >= value ? old : value;
184+
}
185+
186+
static inline int64_t opal_atomic_min_fetch_64 (opal_atomic_int64_t *addr, int64_t value)
187+
{
188+
int64_t old = opal_atomic_fetch_min_64 (addr, value);
189+
return old <= value ? old : value;
190+
}
191+
192+
static inline int64_t opal_atomic_max_fetch_64 (opal_atomic_int64_t *addr, int64_t value)
193+
{
194+
int64_t old = opal_atomic_fetch_max_64 (addr, value);
195+
return old >= value ? old : value;
196+
}
197+
198+
#define OPAL_ATOMIC_LOCK_UNLOCKED false
199+
#define OPAL_ATOMIC_LOCK_LOCKED true
200+
201+
#define OPAL_ATOMIC_LOCK_INIT ATOMIC_FLAG_INIT
202+
203+
typedef atomic_flag opal_atomic_lock_t;
204+
205+
/*
206+
* Lock initialization function. It set the lock to UNLOCKED.
207+
*/
208+
static inline void opal_atomic_lock_init (opal_atomic_lock_t *lock, bool value)
209+
{
210+
atomic_flag_clear (lock);
211+
}
212+
213+
214+
static inline int opal_atomic_trylock (opal_atomic_lock_t *lock)
215+
{
216+
return (int) atomic_flag_test_and_set (lock);
217+
}
218+
219+
220+
static inline void opal_atomic_lock(opal_atomic_lock_t *lock)
221+
{
222+
while (opal_atomic_trylock (lock)) {
223+
}
224+
}
225+
226+
227+
static inline void opal_atomic_unlock (opal_atomic_lock_t *lock)
228+
{
229+
atomic_flag_clear (lock);
230+
}
231+
232+
/* NTH: will probably have to make this stronger to avoid using a lock-based cmpxchng 128 */
233+
#if HAVE_OPAL_INT128_T
234+
235+
#define opal_atomic_compare_exchange_strong_128 atomic_compare_exchange_strong
236+
#define OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_128 1
237+
238+
#endif
239+
240+
#endif /* !defined(OPAL_ATOMIC_STDC_H) */

opal/include/opal_stdatomic.h

+28
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@
1414

1515
#include "opal_stdint.h"
1616

17+
#if !OPAL_C_HAVE__ATOMIC
18+
19+
typedef volatile int opal_atomic_int_t;
1720
typedef volatile long opal_atomic_long_t;
1821

1922
typedef volatile int32_t opal_atomic_int32_t;
@@ -22,6 +25,7 @@ typedef volatile int64_t opal_atomic_int64_t;
2225
typedef volatile uint64_t opal_atomic_uint64_t;
2326

2427
typedef volatile size_t opal_atomic_size_t;
28+
typedef volatile ssize_t opal_atomic_ssize_t;
2529
typedef volatile intptr_t opal_atomic_intptr_t;
2630
typedef volatile uintptr_t opal_atomic_uintptr_t;
2731

@@ -31,5 +35,29 @@ typedef volatile opal_int128_t opal_atomic_int128_t;
3135

3236
#endif
3337

38+
#else /* OPAL_HAVE_C__ATOMIC */
39+
40+
#include <stdatomic.h>
41+
42+
typedef atomic_int opal_atomic_int_t;
43+
typedef atomic_long opal_atomic_long_t;
44+
45+
typedef _Atomic int32_t opal_atomic_int32_t;
46+
typedef _Atomic uint32_t opal_atomic_uint32_t;
47+
typedef _Atomic int64_t opal_atomic_int64_t;
48+
typedef _Atomic uint64_t opal_atomic_uint64_t;
49+
50+
typedef _Atomic size_t opal_atomic_size_t;
51+
typedef _Atomic ssize_t opal_atomic_ssize_t;
52+
typedef _Atomic intptr_t opal_atomic_intptr_t;
53+
typedef _Atomic uintptr_t opal_atomic_uintptr_t;
54+
55+
#if HAVE_OPAL_INT128_T
56+
57+
typedef _Atomic opal_int128_t opal_atomic_int128_t;
58+
59+
#endif
60+
61+
#endif /* OPAL_HAVE_C__ATOMIC */
3462

3563
#endif /* !defined(OPAL_STDATOMIC_H) */

opal/include/opal_stdint.h

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
#ifndef OPAL_STDINT_H
2929
#define OPAL_STDINT_H 1
3030

31+
#include "opal_config.h"
32+
3133
/*
3234
* Include what we can and define what is missing.
3335
*/

opal/mca/btl/vader/btl_vader_component.c

+4-1
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ static int mca_btl_base_vader_modex_send (void)
365365
return rc;
366366
}
367367

368+
#if OPAL_BTL_VADER_HAVE_XPMEM || OPAL_BTL_VADER_HAVE_CMA || OPAL_BTL_VADER_HAVE_KNEM
368369
static void mca_btl_vader_select_next_single_copy_mechanism (void)
369370
{
370371
for (int i = 0 ; single_copy_mechanisms[i].value != MCA_BTL_VADER_NONE ; ++i) {
@@ -374,10 +375,13 @@ static void mca_btl_vader_select_next_single_copy_mechanism (void)
374375
}
375376
}
376377
}
378+
#endif
377379

378380
static void mca_btl_vader_check_single_copy (void)
379381
{
382+
#if OPAL_BTL_VADER_HAVE_XPMEM || OPAL_BTL_VADER_HAVE_CMA || OPAL_BTL_VADER_HAVE_KNEM
380383
int initial_mechanism = mca_btl_vader_component.single_copy_mechanism;
384+
#endif
381385

382386
#if OPAL_BTL_VADER_HAVE_XPMEM
383387
if (MCA_BTL_VADER_XPMEM == mca_btl_vader_component.single_copy_mechanism) {
@@ -520,7 +524,6 @@ static mca_btl_base_module_t **mca_btl_vader_component_init (int *num_btls,
520524
mca_btl_vader_check_single_copy ();
521525

522526
if (MCA_BTL_VADER_XPMEM != mca_btl_vader_component.single_copy_mechanism) {
523-
const char *base_dir = opal_process_info.proc_session_dir;
524527
char *sm_file;
525528

526529
rc = asprintf(&sm_file, "%s" OPAL_PATH_SEP "vader_segment.%s.%x.%d", mca_btl_vader_component.backing_directory,

0 commit comments

Comments
 (0)