10#if defined(AO_HAVE_test_and_set_acquire)&&!defined(USE_LEGACY_ATOMICS)
11#define USE_LIBAO_ATOMICS
16#if defined(USE_PTHREAD_MUTEXES)
22#define _papi_hwd_lock(lck) \
25 pthread_mutex_lock (&_papi_hwd_lock_data[lck]); \
27#define _papi_hwd_unlock(lck) \
30 pthread_mutex_unlock(&_papi_hwd_lock_data[lck]); \
33#elif defined(USE_LIBAO_ATOMICS)
36#define _papi_hwd_lock(lck) {while (AO_test_and_set_acquire(&_papi_hwd_lock_data[lck]) != AO_TS_CLEAR) { ; } }
37#define _papi_hwd_unlock(lck) { AO_CLEAR(&_papi_hwd_lock_data[lck]); }
50#ifdef __INTEL_COMPILER
51#define _papi_hwd_lock(lck) { while(_InterlockedCompareExchange_acq(&_papi_hwd_lock_data[lck],MUTEX_CLOSED,MUTEX_OPEN) != MUTEX_OPEN) { ; } }
52#define _papi_hwd_unlock(lck) { _InterlockedExchange((volatile int *)&_papi_hwd_lock_data[lck], MUTEX_OPEN); }
54#define _papi_hwd_lock(lck) \
57 __asm__ __volatile__ ("mov ar.ccv=%0;;" :: "r"(MUTEX_OPEN)); \
58 __asm__ __volatile__ ("cmpxchg4.acq %0=[%1],%2,ar.ccv" : "=r"(res) : "r"(&_papi_hwd_lock_data[lck]), "r"(MUTEX_CLOSED) : "memory"); \
59 } while (res != MUTEX_OPEN); }
61#define _papi_hwd_unlock(lck) { __asm__ __volatile__ ("st4.rel [%0]=%1" : : "r"(&_papi_hwd_lock_data[lck]), "r"(MUTEX_OPEN) : "memory"); }
70#define _papi_hwd_lock(lck) \
73 unsigned int res = 0; \
75#define _papi_hwd_unlock(lck) \
78 unsigned int res = 0; \
84#elif defined(__i386__)||defined(__x86_64__)
85#define _papi_hwd_lock(lck) \
88 unsigned int res = 0; \
90 __asm__ __volatile__ ("lock ; " "cmpxchg %1,%2" : "=a"(res) : "q"(MUTEX_CLOSED), "m"(_papi_hwd_lock_data[lck]), "0"(MUTEX_OPEN) : "memory"); \
91 } while(res != (unsigned int)MUTEX_OPEN); \
93#define _papi_hwd_unlock(lck) \
96 unsigned int res = 0; \
97 __asm__ __volatile__ ("xchg %0,%1" : "=r"(res) : "m"(_papi_hwd_lock_data[lck]), "0"(MUTEX_OPEN) : "memory"); \
104#elif defined(__powerpc__)
114static __inline__
unsigned long
115papi_xchg_u32(
volatile void *p,
unsigned long val )
119 __asm__ __volatile__(
"\n\
124 isync":
"=&r"( prev ),
"=m"( *(
volatile unsigned long * ) p )
125 :
"r"( p ),
"r"( val ),
126 "m"( *(
volatile unsigned long * ) p )
132#define _papi_hwd_lock(lck) \
134 unsigned int retval; \
136 retval = papi_xchg_u32(&_papi_hwd_lock_data[lck],MUTEX_CLOSED); \
137 } while(retval != (unsigned int)MUTEX_OPEN); \
139#define _papi_hwd_unlock(lck) \
141 unsigned int retval; \
143 retval = papi_xchg_u32(&_papi_hwd_lock_data[lck],MUTEX_OPEN); \
144 } while(retval != (unsigned int)MUTEX_CLOSED); \
151#elif defined(__sparc__)
153__raw_spin_lock(
volatile unsigned int *
lock )
155 __asm__ __volatile__(
"\n1:\n\t" "ldstub [%0], %%g2\n\t" "orcc %%g2, 0x0, %%g0\n\t" "bne,a 2f\n\t" " ldub [%0], %%g2\n\t" ".subsection 2\n" "2:\n\t" "orcc %%g2, 0x0, %%g0\n\t" "bne,a 2b\n\t" " ldub [%0], %%g2\n\t" "b,a 1b\n\t" ".previous\n":
157 :
"g2",
"memory",
"cc" );
160__raw_spin_unlock(
volatile unsigned int *
lock )
162 __asm__ __volatile__(
"stb %%g0, [%0]"::
"r"(
lock ):
"memory" );
165#define _papi_hwd_lock(lck) __raw_spin_lock(&_papi_hwd_lock_data[lck]);
166#define _papi_hwd_unlock(lck) __raw_spin_unlock(&_papi_hwd_lock_data[lck])
172#elif defined(__arm__)
185#warning "WARNING! Verify mutexes work on ARM!"
190#define MUTEX_SET(tsl) ({ \
193 "swpb %0, %1, [%2]\n\t" \
194 "eor %0, %0, #1\n\t" \
196 : "r" (1), "r" (tsl) \
201#define _papi_hwd_lock(lck) MUTEX_SET(lck)
202#define _papi_hwd_unlock(lck) (*(volatile int *)(lck) = 0)
207static inline int __arm_papi_spin_lock (
volatile unsigned int *
lock)
212 asm volatile (
"swp %0, %1, [%2]"
214 :
"0" (1),
"r" (
lock)
220#define _papi_hwd_lock(lck) { rmb(); __arm_papi_spin_lock(&_papi_hwd_lock_data[lck]); rmb(); }
221#define _papi_hwd_unlock(lck) { rmb(); _papi_hwd_lock_data[lck] = 0; rmb(); }
223#elif defined(__mips__)
224static inline void __raw_spin_lock(
volatile unsigned int *
lock)
227 __asm__ __volatile__(
228 " .set noreorder # __raw_spin_lock \n"
233#
if __mips_isa_rev < 6
246static inline void __raw_spin_unlock(
volatile unsigned int *
lock)
248 __asm__ __volatile__(
249 " .set noreorder # __raw_spin_unlock \n"
257#define _papi_hwd_lock(lck) __raw_spin_lock(&_papi_hwd_lock_data[lck]);
258#define _papi_hwd_unlock(lck) __raw_spin_unlock(&_papi_hwd_lock_data[lck])
261#error "_papi_hwd_lock/unlock undefined!"
volatile unsigned int _papi_hwd_lock_data[PAPI_MAX_LOCK]