Blame src/linux-lock.h

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