Skip to content

Commit e9d7bb9

Browse files
committed
Make spinlocks mandatory
With the change to make compare and swap mandatory, we can always implement spinlocks, so make them mandatory and simplify the interface. Signed-off-by: Brian Barrett <[email protected]>
1 parent 799aedd commit e9d7bb9

File tree

11 files changed

+154
-164
lines changed

11 files changed

+154
-164
lines changed

opal/include/opal/sys/Makefile.am

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ headers += \
3434
opal/sys/atomic_impl.h \
3535
opal/sys/atomic_impl_ptr_cswap.h \
3636
opal/sys/atomic_impl_ptr_swap.h \
37+
opal/sys/atomic_impl_spinlock.h \
3738
opal/sys/timer.h \
3839
opal/sys/cma.h
3940

opal/include/opal/sys/arm64/atomic.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,15 @@ static inline int64_t opal_atomic_swap_64(opal_atomic_int64_t *addr, int64_t new
255255
#include "opal/sys/atomic_impl_ptr_swap.h"
256256

257257

258+
/**********************************************************************
259+
*
260+
* Atomic spinlocks
261+
*
262+
*********************************************************************/
263+
264+
#include "opal/sys/atomic_impl_spinlock.h"
265+
266+
258267
/**********************************************************************
259268
*
260269
* Atomic math operations

opal/include/opal/sys/atomic.h

Lines changed: 5 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@
4141
* The following #defines will be true / false based on
4242
* assembly support:
4343
*
44-
* - \c OPAL_HAVE_ATOMIC_SPINLOCKS atomic spinlocks
45-
*
4644
* Note that for the Atomic math, atomic add/sub may be implemented as
4745
* C code using opal_atomic_compare_exchange. The appearance of atomic
4846
* operation will be upheld in these cases.
@@ -66,27 +64,6 @@
6664

6765

6866
BEGIN_C_DECLS
69-
/**********************************************************************
70-
*
71-
* Data structures for atomic ops
72-
*
73-
*********************************************************************/
74-
/**
75-
* Volatile lock object (with optional padding).
76-
*
77-
* \note The internals of the lock are included here, but should be
78-
* considered private. The implementation currently in use may choose
79-
* to use an int or unsigned char as the lock value - the user is not
80-
* informed either way.
81-
*/
82-
struct opal_atomic_lock_t {
83-
union {
84-
opal_atomic_int32_t lock; /**< The lock address (an integer) */
85-
volatile unsigned char sparc_lock; /**< The lock address on sparc */
86-
char padding[sizeof(int)]; /**< Array for optional padding */
87-
} u;
88-
};
89-
typedef struct opal_atomic_lock_t opal_atomic_lock_t;
9067

9168
/**********************************************************************
9269
*
@@ -105,16 +82,6 @@ typedef struct opal_atomic_lock_t opal_atomic_lock_t;
10582
#define OPAL_HAVE_INLINE_ATOMIC_XOR_64 1
10683
#define OPAL_HAVE_INLINE_ATOMIC_SUB_64 1
10784

108-
/**
109-
* Enumeration of lock states
110-
*/
111-
enum { OPAL_ATOMIC_LOCK_UNLOCKED = 0, OPAL_ATOMIC_LOCK_LOCKED = 1 };
112-
113-
# define OPAL_ATOMIC_LOCK_INIT \
114-
{ \
115-
.u = {.lock = OPAL_ATOMIC_LOCK_UNLOCKED } \
116-
}
117-
11885
/**********************************************************************
11986
*
12087
* Load the appropriate architecture files and set some reasonable
@@ -374,73 +341,39 @@ static inline intptr_t opal_atomic_swap_ptr(opal_atomic_intptr_t *addr, intptr_t
374341

375342
/**********************************************************************
376343
*
377-
* Atomic spinlocks - always inlined, if have atomic compare-and-swap
344+
* Atomic spinlocks
378345
*
379346
*********************************************************************/
380-
381-
# if !defined(OPAL_HAVE_ATOMIC_SPINLOCKS) && !defined(DOXYGEN)
382-
/* 0 is more like "pending" - we'll fix up at the end after all
383-
the static inline functions are declared */
384-
# define OPAL_HAVE_ATOMIC_SPINLOCKS 0
385-
# endif
386-
387-
# if defined(DOXYGEN) || OPAL_HAVE_ATOMIC_SPINLOCKS \
388-
|| (OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 || OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64)
389-
390347
/**
391348
* Initialize a lock to value
392349
*
393350
* @param lock Address of the lock
394351
* @param value Initial value to set lock to
395352
*/
396-
# if OPAL_HAVE_ATOMIC_SPINLOCKS == 0
397-
static inline
398-
# endif
399-
void
400-
opal_atomic_lock_init(opal_atomic_lock_t *lock, int32_t value);
353+
static inline void opal_atomic_lock_init(opal_atomic_lock_t *lock, int32_t value);
401354

402355
/**
403356
* Try to acquire a lock.
404357
*
405358
* @param lock Address of the lock.
406359
* @return 0 if the lock was acquired, 1 otherwise.
407360
*/
408-
# if OPAL_HAVE_ATOMIC_SPINLOCKS == 0
409-
static inline
410-
# endif
411-
int
412-
opal_atomic_trylock(opal_atomic_lock_t *lock);
361+
static inline int opal_atomic_trylock(opal_atomic_lock_t *lock);
413362

414363
/**
415364
* Acquire a lock by spinning.
416365
*
417366
* @param lock Address of the lock.
418367
*/
419-
# if OPAL_HAVE_ATOMIC_SPINLOCKS == 0
420-
static inline
421-
# endif
422-
void
423-
opal_atomic_lock(opal_atomic_lock_t *lock);
368+
static inline void opal_atomic_lock(opal_atomic_lock_t *lock);
424369

425370
/**
426371
* Release a lock.
427372
*
428373
* @param lock Address of the lock.
429374
*/
430-
# if OPAL_HAVE_ATOMIC_SPINLOCKS == 0
431-
static inline
432-
# endif
433-
void
434-
opal_atomic_unlock(opal_atomic_lock_t *lock);
435-
436-
# if OPAL_HAVE_ATOMIC_SPINLOCKS == 0
437-
# undef OPAL_HAVE_ATOMIC_SPINLOCKS
438-
# define OPAL_HAVE_ATOMIC_SPINLOCKS \
439-
(OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_32 || OPAL_HAVE_ATOMIC_COMPARE_EXCHANGE_64)
440-
# define OPAL_NEED_INLINE_ATOMIC_SPINLOCKS 1
441-
# endif
375+
static inline void opal_atomic_unlock(opal_atomic_lock_t *lock);
442376

443-
# endif /* OPAL_HAVE_ATOMIC_SPINLOCKS */
444377

445378
/**********************************************************************
446379
*

opal/include/opal/sys/atomic_impl.h

Lines changed: 0 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -321,44 +321,3 @@ static inline intptr_t opal_atomic_sub_fetch_ptr(opal_atomic_intptr_t *addr, voi
321321
return 0;
322322
# endif
323323
}
324-
325-
326-
/**********************************************************************
327-
*
328-
* Atomic spinlocks
329-
*
330-
*********************************************************************/
331-
#ifdef OPAL_NEED_INLINE_ATOMIC_SPINLOCKS
332-
333-
/*
334-
* Lock initialization function. It set the lock to UNLOCKED.
335-
*/
336-
static inline void opal_atomic_lock_init(opal_atomic_lock_t *lock, int32_t value)
337-
{
338-
lock->u.lock = value;
339-
}
340-
341-
static inline int opal_atomic_trylock(opal_atomic_lock_t *lock)
342-
{
343-
int32_t unlocked = OPAL_ATOMIC_LOCK_UNLOCKED;
344-
bool ret = opal_atomic_compare_exchange_strong_acq_32(&lock->u.lock, &unlocked,
345-
OPAL_ATOMIC_LOCK_LOCKED);
346-
return (ret == false) ? 1 : 0;
347-
}
348-
349-
static inline void opal_atomic_lock(opal_atomic_lock_t *lock)
350-
{
351-
while (opal_atomic_trylock(lock)) {
352-
while (lock->u.lock == OPAL_ATOMIC_LOCK_LOCKED) {
353-
/* spin */;
354-
}
355-
}
356-
}
357-
358-
static inline void opal_atomic_unlock(opal_atomic_lock_t *lock)
359-
{
360-
opal_atomic_wmb();
361-
lock->u.lock = OPAL_ATOMIC_LOCK_UNLOCKED;
362-
}
363-
364-
#endif /* OPAL_HAVE_ATOMIC_SPINLOCKS */
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
3+
* University Research and Technology
4+
* Corporation. All rights reserved.
5+
* Copyright (c) 2004-2014 The University of Tennessee and The University
6+
* of Tennessee Research Foundation. All rights
7+
* reserved.
8+
* Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9+
* University of Stuttgart. All rights reserved.
10+
* Copyright (c) 2004-2005 The Regents of the University of California.
11+
* All rights reserved.
12+
* Copyright (c) 2010-2014 Cisco Systems, Inc. All rights reserved.
13+
* Copyright (c) 2012-2018 Los Alamos National Security, LLC. All rights
14+
* reserved.
15+
* Copyright (c) 2022 Amazon.com, Inc. or its affiliates.
16+
* All Rights reserved.
17+
* $COPYRIGHT$
18+
*
19+
* Additional copyrights may follow
20+
*
21+
* $HEADER$
22+
*
23+
* Compare-and-swap based implementation of the atomic interface
24+
*/
25+
26+
#ifndef ATOMIC_SPINLOCK_IMPL_H
27+
#define ATOMIC_SPINLOCK_IMPL_H
28+
29+
static inline void opal_atomic_lock_init(opal_atomic_lock_t *lock, int32_t value)
30+
{
31+
*lock = value;
32+
opal_atomic_wmb();
33+
}
34+
35+
static inline int opal_atomic_trylock(opal_atomic_lock_t *lock)
36+
{
37+
int32_t unlocked = OPAL_ATOMIC_LOCK_UNLOCKED;
38+
bool ret = opal_atomic_compare_exchange_strong_acq_32(lock, &unlocked,
39+
OPAL_ATOMIC_LOCK_LOCKED);
40+
return (ret == false) ? 1 : 0;
41+
}
42+
43+
static inline void opal_atomic_lock(opal_atomic_lock_t *lock)
44+
{
45+
while (opal_atomic_trylock(lock)) {
46+
while (*lock == OPAL_ATOMIC_LOCK_LOCKED) {
47+
/* spin */;
48+
}
49+
}
50+
}
51+
52+
static inline void opal_atomic_unlock(opal_atomic_lock_t *lock)
53+
{
54+
opal_atomic_wmb();
55+
*lock = OPAL_ATOMIC_LOCK_UNLOCKED;
56+
}
57+
58+
#endif /* #ifndef ATOMIC_SPINLOCK_IMPL_H */

opal/include/opal/sys/atomic_stdc.h

Lines changed: 31 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@
5050
# define OPAL_HAVE_ATOMIC_MIN_64 1
5151
# define OPAL_HAVE_ATOMIC_MAX_64 1
5252

53-
# define OPAL_HAVE_ATOMIC_SPINLOCKS 1
54-
5553

5654
/**********************************************************************
5755
*
@@ -162,6 +160,36 @@ opal_atomic_compare_exchange_strong_128(opal_atomic_int128_t *addr, opal_int128_
162160
atomic_exchange_explicit((_Atomic unsigned long *) addr, value, memory_order_relaxed)
163161

164162

163+
/**********************************************************************
164+
*
165+
* Atomic spinlocks
166+
*
167+
*********************************************************************/
168+
/*
169+
* Lock initialization function. It set the lock to UNLOCKED.
170+
*/
171+
static inline void opal_atomic_lock_init(opal_atomic_lock_t *lock, bool value)
172+
{
173+
atomic_flag_clear_explicit(lock, memory_order_relaxed);
174+
}
175+
176+
static inline int opal_atomic_trylock(opal_atomic_lock_t *lock)
177+
{
178+
return (int) atomic_flag_test_and_set(lock);
179+
}
180+
181+
static inline void opal_atomic_lock(opal_atomic_lock_t *lock)
182+
{
183+
while (opal_atomic_trylock(lock)) {
184+
}
185+
}
186+
187+
static inline void opal_atomic_unlock(opal_atomic_lock_t *lock)
188+
{
189+
atomic_flag_clear(lock);
190+
}
191+
192+
165193
# define OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(op, bits, type, operator) \
166194
static inline type opal_atomic_fetch_##op##_##bits(opal_atomic_##type *addr, type value) \
167195
{ \
@@ -173,6 +201,7 @@ opal_atomic_compare_exchange_strong_128(opal_atomic_int128_t *addr, opal_int128_
173201
return atomic_fetch_##op##_explicit(addr, value, memory_order_relaxed) operator value; \
174202
}
175203

204+
176205
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(add, 32, int32_t, +)
177206
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(add, 64, int64_t, +)
178207
OPAL_ATOMIC_STDC_DEFINE_FETCH_OP(add, size_t, size_t, +)
@@ -265,35 +294,4 @@ static inline int64_t opal_atomic_max_fetch_64(opal_atomic_int64_t *addr, int64_
265294
return old >= value ? old : value;
266295
}
267296

268-
# define OPAL_ATOMIC_LOCK_UNLOCKED false
269-
# define OPAL_ATOMIC_LOCK_LOCKED true
270-
271-
# define OPAL_ATOMIC_LOCK_INIT ATOMIC_FLAG_INIT
272-
273-
typedef atomic_flag opal_atomic_lock_t;
274-
275-
/*
276-
* Lock initialization function. It set the lock to UNLOCKED.
277-
*/
278-
static inline void opal_atomic_lock_init(opal_atomic_lock_t *lock, bool value)
279-
{
280-
atomic_flag_clear_explicit(lock, memory_order_relaxed);
281-
}
282-
283-
static inline int opal_atomic_trylock(opal_atomic_lock_t *lock)
284-
{
285-
return (int) atomic_flag_test_and_set(lock);
286-
}
287-
288-
static inline void opal_atomic_lock(opal_atomic_lock_t *lock)
289-
{
290-
while (opal_atomic_trylock(lock)) {
291-
}
292-
}
293-
294-
static inline void opal_atomic_unlock(opal_atomic_lock_t *lock)
295-
{
296-
atomic_flag_clear(lock);
297-
}
298-
299297
#endif /* !defined(OPAL_ATOMIC_STDC_H) */

0 commit comments

Comments
 (0)