|
Packit |
577717 |
#ifndef _LINUX_LOCK_H
|
|
Packit |
577717 |
#define _LINUX_LOCK_H
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "mb.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Locking functions */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(USE_PTHREAD_MUTEXES)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <pthread.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
extern pthread_mutex_t _papi_hwd_lock_data[PAPI_MAX_LOCK];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) \
|
|
Packit |
577717 |
do \
|
|
Packit |
577717 |
{ \
|
|
Packit |
577717 |
pthread_mutex_lock (&_papi_hwd_lock_data[lck]); \
|
|
Packit |
577717 |
} while(0)
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) \
|
|
Packit |
577717 |
do \
|
|
Packit |
577717 |
{ \
|
|
Packit |
577717 |
pthread_mutex_unlock(&_papi_hwd_lock_data[lck]); \
|
|
Packit |
577717 |
} while(0)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
|
|
Packit |
577717 |
extern volatile unsigned int _papi_hwd_lock_data[PAPI_MAX_LOCK];
|
|
Packit |
577717 |
#define MUTEX_OPEN 0
|
|
Packit |
577717 |
#define MUTEX_CLOSED 1
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/********/
|
|
Packit |
577717 |
/* ia64 */
|
|
Packit |
577717 |
/********/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if defined(__ia64__)
|
|
Packit |
577717 |
#ifdef __INTEL_COMPILER
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) { while(_InterlockedCompareExchange_acq(&_papi_hwd_lock_data[lck],MUTEX_CLOSED,MUTEX_OPEN) != MUTEX_OPEN) { ; } }
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) { _InterlockedExchange((volatile int *)&_papi_hwd_lock_data[lck], MUTEX_OPEN); }
|
|
Packit |
577717 |
#else /* GCC */
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) \
|
|
Packit |
577717 |
{ int res = 0; \
|
|
Packit |
577717 |
do { \
|
|
Packit |
577717 |
__asm__ __volatile__ ("mov ar.ccv=%0;;" :: "r"(MUTEX_OPEN)); \
|
|
Packit |
577717 |
__asm__ __volatile__ ("cmpxchg4.acq %0=[%1],%2,ar.ccv" : "=r"(res) : "r"(&_papi_hwd_lock_data[lck]), "r"(MUTEX_CLOSED) : "memory"); \
|
|
Packit |
577717 |
} while (res != MUTEX_OPEN); }
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) { __asm__ __volatile__ ("st4.rel [%0]=%1" : : "r"(&_papi_hwd_lock_data[lck]), "r"(MUTEX_OPEN) : "memory"); }
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/***********/
|
|
Packit |
577717 |
/* x86 */
|
|
Packit |
577717 |
/***********/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#elif defined(__i386__)||defined(__x86_64__)
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) \
|
|
Packit |
577717 |
do \
|
|
Packit |
577717 |
{ \
|
|
Packit |
577717 |
unsigned int res = 0; \
|
|
Packit |
577717 |
do { \
|
|
Packit |
577717 |
__asm__ __volatile__ ("lock ; " "cmpxchg %1,%2" : "=a"(res) : "q"(MUTEX_CLOSED), "m"(_papi_hwd_lock_data[lck]), "0"(MUTEX_OPEN) : "memory"); \
|
|
Packit |
577717 |
} while(res != (unsigned int)MUTEX_OPEN); \
|
|
Packit |
577717 |
} while(0)
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) \
|
|
Packit |
577717 |
do \
|
|
Packit |
577717 |
{ \
|
|
Packit |
577717 |
unsigned int res = 0; \
|
|
Packit |
577717 |
__asm__ __volatile__ ("xchg %0,%1" : "=r"(res) : "m"(_papi_hwd_lock_data[lck]), "0"(MUTEX_OPEN) : "memory"); \
|
|
Packit |
577717 |
} while(0)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/***************/
|
|
Packit |
577717 |
/* power */
|
|
Packit |
577717 |
/***************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#elif defined(__powerpc__)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* These functions are slight modifications of the functions in
|
|
Packit |
577717 |
* /usr/include/asm-ppc/system.h.
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* We can't use the ones in system.h directly because they are defined
|
|
Packit |
577717 |
* only when __KERNEL__ is defined.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static __inline__ unsigned long
|
|
Packit |
577717 |
papi_xchg_u32( volatile void *p, unsigned long val )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned long prev;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
__asm__ __volatile__( "\n\
|
|
Packit |
577717 |
sync \n\
|
|
Packit |
577717 |
1: lwarx %0,0,%2 \n\
|
|
Packit |
577717 |
stwcx. %3,0,%2 \n\
|
|
Packit |
577717 |
bne- 1b \n\
|
|
Packit |
577717 |
isync":"=&r"( prev ), "=m"( *( volatile unsigned long * ) p )
|
|
Packit |
577717 |
:"r"( p ), "r"( val ),
|
|
Packit |
577717 |
"m"( *( volatile unsigned long * ) p )
|
|
Packit |
577717 |
:"cc", "memory" );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return prev;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) \
|
|
Packit |
577717 |
do { \
|
|
Packit |
577717 |
unsigned int retval; \
|
|
Packit |
577717 |
do { \
|
|
Packit |
577717 |
retval = papi_xchg_u32(&_papi_hwd_lock_data[lck],MUTEX_CLOSED); \
|
|
Packit |
577717 |
} while(retval != (unsigned int)MUTEX_OPEN); \
|
|
Packit |
577717 |
} while(0)
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) \
|
|
Packit |
577717 |
do { \
|
|
Packit |
577717 |
unsigned int retval; \
|
|
Packit |
577717 |
do { \
|
|
Packit |
577717 |
retval = papi_xchg_u32(&_papi_hwd_lock_data[lck],MUTEX_OPEN); \
|
|
Packit |
577717 |
} while(retval != (unsigned int)MUTEX_CLOSED); \
|
|
Packit |
577717 |
} while (0)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*****************/
|
|
Packit |
577717 |
/* SPARC */
|
|
Packit |
577717 |
/*****************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#elif defined(__sparc__)
|
|
Packit |
577717 |
static inline void
|
|
Packit |
577717 |
__raw_spin_lock( volatile unsigned int *lock )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
__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": /* no outputs */
|
|
Packit |
577717 |
:"r"( lock )
|
|
Packit |
577717 |
:"g2", "memory", "cc" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
static inline void
|
|
Packit |
577717 |
__raw_spin_unlock( volatile unsigned int *lock )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
__asm__ __volatile__( "stb %%g0, [%0]"::"r"( lock ):"memory" );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) __raw_spin_lock(&_papi_hwd_lock_data[lck]);
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) __raw_spin_unlock(&_papi_hwd_lock_data[lck])
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*******************/
|
|
Packit |
577717 |
/* ARM */
|
|
Packit |
577717 |
/*******************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#elif defined(__arm__)
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#if 0
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* OLD CODE FROM VINCE BELOW */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* FIXME */
|
|
Packit |
577717 |
/* not sure if this even works */
|
|
Packit |
577717 |
/* also the various flavors of ARM */
|
|
Packit |
577717 |
/* have differing levels of atomic */
|
|
Packit |
577717 |
/* instruction support. A proper */
|
|
Packit |
577717 |
/* implementation needs to handle this :( */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#warning "WARNING! Verify mutexes work on ARM!"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* For arm/gcc, 0 is clear, 1 is set.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
#define MUTEX_SET(tsl) ({ \
|
|
Packit |
577717 |
int __r; \
|
|
Packit |
577717 |
asm volatile( \
|
|
Packit |
577717 |
"swpb %0, %1, [%2]\n\t" \
|
|
Packit |
577717 |
"eor %0, %0, #1\n\t" \
|
|
Packit |
577717 |
: "=&r" (__r) \
|
|
Packit |
577717 |
: "r" (1), "r" (tsl) \
|
|
Packit |
577717 |
); \
|
|
Packit |
577717 |
__r & 1; \
|
|
Packit |
577717 |
})
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) MUTEX_SET(lck)
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) (*(volatile int *)(lck) = 0)
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* NEW CODE FROM PHIL */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline int __arm_papi_spin_lock (volatile unsigned int *lock)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int val;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
do
|
|
Packit |
577717 |
asm volatile ("swp %0, %1, [%2]"
|
|
Packit |
577717 |
: "=r" (val)
|
|
Packit |
577717 |
: "0" (1), "r" (lock)
|
|
Packit |
577717 |
: "memory");
|
|
Packit |
577717 |
while (val != 0);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) { rmb(); __arm_papi_spin_lock(&_papi_hwd_lock_data[lck]); rmb(); }
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) { rmb(); _papi_hwd_lock_data[lck] = 0; rmb(); }
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#elif defined(__mips__)
|
|
Packit |
577717 |
static inline void __raw_spin_lock(volatile unsigned int *lock)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
unsigned int tmp;
|
|
Packit |
577717 |
__asm__ __volatile__(
|
|
Packit |
577717 |
" .set noreorder # __raw_spin_lock \n"
|
|
Packit |
577717 |
"1: ll %1, %2 \n"
|
|
Packit |
577717 |
" bnez %1, 1b \n"
|
|
Packit |
577717 |
" li %1, 1 \n"
|
|
Packit |
577717 |
" sc %1, %0 \n"
|
|
Packit |
577717 |
" beqzl %1, 1b \n"
|
|
Packit |
577717 |
" nop \n"
|
|
Packit |
577717 |
" sync \n"
|
|
Packit |
577717 |
" .set reorder \n"
|
|
Packit |
577717 |
: "=m" (*lock), "=&r" (tmp)
|
|
Packit |
577717 |
: "m" (*lock)
|
|
Packit |
577717 |
: "memory");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static inline void __raw_spin_unlock(volatile unsigned int *lock)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
__asm__ __volatile__(
|
|
Packit |
577717 |
" .set noreorder # __raw_spin_unlock \n"
|
|
Packit |
577717 |
" sync \n"
|
|
Packit |
577717 |
" sw $0, %0 \n"
|
|
Packit |
577717 |
" .set\treorder \n"
|
|
Packit |
577717 |
: "=m" (*lock)
|
|
Packit |
577717 |
: "m" (*lock)
|
|
Packit |
577717 |
: "memory");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
#define _papi_hwd_lock(lck) __raw_spin_lock(&_papi_hwd_lock_data[lck]);
|
|
Packit |
577717 |
#define _papi_hwd_unlock(lck) __raw_spin_unlock(&_papi_hwd_lock_data[lck])
|
|
Packit |
577717 |
#else
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#error "_papi_hwd_lock/unlock undefined!"
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#endif /* defined(USE_PTHREAD_MUTEXES) */
|