4
* This file attempts to implement spin locks for various platforms and/or CPU
10
#define DEBUG_SPINLOCK 0
16
# warning SPINLOCK: openpa
19
# include "opa_primitives.h"
20
# define LOCK_T OPA_int_t
21
# define TESTANDSET(x) OPA_swap_int((x), 1)
22
# define MEMORY_BARRIER OPA_read_write_barrier
24
#elif (defined(PPC) || defined(__PPC__) || defined(__PPC))
26
# warning SPINLOCK: PPC
30
//# define TESTANDSET testandset
31
//# define TESTANDSET acquireLock
32
# define armci_acquire_spinlock acquire_spinlock
33
# define armci_release_spinlock release_spinlock
34
# define MEMORY_BARRIER memory_barrier
35
static int testandset(void *spinlock) {
37
atomic_exchange(&v,spinlock,sizeof(int));
40
static void memory_barrier() {
41
__asm__ __volatile__ ("sync" : : : "memory");
44
#elif defined(__i386__) || defined(__x86_64__)
46
# warning SPINLOCK: x86_64
49
# include "atomics-i386.h"
50
static int testandset(void *spinlock) {
52
atomic_exchange(&v,spinlock,sizeof(int));
55
# define TESTANDSET testandset
59
# warning SPINLOCK: ia64
62
# include "atomic_ops_ia64.h"
63
static int testandset(void *spinlock) {
66
atomic_swap_int(spinlock, val, &res);
69
# define TESTANDSET testandset
73
# warning SPINLOCK: DECOSF
75
# error "no implementation"
79
# warning SPINLOCK: SGI
83
# define TESTANDSET(x) __lock_test_and_set((x), 1)
84
# define RELEASE_SPINLOCK __lock_release
86
/*#elif defined(AIX)*/
87
#elif HAVE_SYS_ATOMIC_OP_H
89
# warning SPINLOCK: sys/atomic_op.h (AIX)
91
# include <sys/atomic_op.h>
93
# define TESTANDSET(x) (_check_lock((x), 0, 1)==TRUE)
94
# define RELEASE_SPINLOCK(x) _clear_lock((x),0)
96
#elif defined(SOLARIS)
98
# warning SPINLOCK: SOLARIS
100
# include <sys/atomic.h>
101
# include <sys/machlock.h>
103
# define TESTANDSET(x) (!_lock_try((x)))
104
# define RELEASE_SPINLOCK _lock_clear
108
#elif defined(HPUX__)
110
# warning SPINLOCK: HPUX__
112
extern int _acquire_lock();
113
extern void _release_lock();
115
# define TESTANDSET(x) (!_acquire_lock((x)))
116
# define RELEASE_SPINLOCK _release_lock
118
#elif defined(HPUX) && defined(__ia64) /* HPUX on IA64, non gcc */
120
# warning SPINLOCK: HPUX ia64
123
typedef unsigned int slock_t;
124
# include <ia64/sys/inline.h>
125
# define TESTANDSET(lock) _Asm_xchg(_SZ_W, lock, 1, _LDHINT_NONE)
126
# define RELEASE_SPINLOCK(lock) (*((volatile LOCK_T *) (lock)) = 0)
130
# warning SPINLOCK: NEC
132
extern ullong ts1am_2me();
133
# define LOCK_T ullong
134
# define _LKWD (1ULL << 63)
136
# define TESTANDSET(x) ((_LKWD & ts1am_2me(_LKWD, 0xffULL, (ullong)(x))))
137
# define MEMORY_BARRIER mpisx_clear_cache
138
extern void mpisx_clear_cache();
139
# define RELEASE_SPINLOCK(x) ts1am_2me(0ULL, 0xffULL, (ullong)x);
159
/* make sure that locks are not sharing the same cache line */
161
double lock[DBL_PAD];
167
#define PAD_LOCK_T pad_lock_t
169
static inline void armci_init_spinlock(LOCK_T *mutex)
172
OPA_store_int(mutex, 0);
180
static inline void armci_acquire_spinlock(LOCK_T *mutex)
182
#if defined(BGML) || defined(DCMF)
185
int loop=0, maxloop =10;
187
while (TESTANDSET(mutex)){
192
printf("%d:spinlock sleeping\n",armci_me); fflush(stdout);
201
#ifdef RELEASE_SPINLOCK
202
# ifdef MEMORY_BARRIER
203
# define armci_release_spinlock(x) MEMORY_BARRIER(); RELEASE_SPINLOCK(x)
205
# define armci_release_spinlock(x) RELEASE_SPINLOCK(x)
208
static inline void armci_release_spinlock(LOCK_T *mutex)
210
#if defined(BGML) || defined(DCMF)
213
# ifdef MEMORY_BARRIER
217
OPA_store_int(mutex, 0);
221
# ifdef MEMORY_BARRIER
224
# if (defined(MACX)||defined(LINUX)) && defined(__GNUC__) && defined(__ppc__)
225
__asm__ __volatile__ ("isync" : : : "memory");
229
#endif /* RELEASE_SPINLOCK */
231
#endif /* TESTANDSET */
233
#endif /* SPINLOCK */
235
#endif /* SPINLOCK_H */