11 #include <sys/syscall.h> 27 #include <sys/resource.h> 29 #include <sys/times.h> 33 #include "perfmon/pfmlib_itanium2.h" 34 #include "perfmon/pfmlib_montecito.h" 38 #include <sys/platform/ppc.h> 41 #if defined(HAVE_MMTIMER) 43 #include <linux/mmtimer.h> 44 #include <sys/ioctl.h> 45 #ifndef MMTIMER_FULLNAME 46 #define MMTIMER_FULLNAME "/dev/mmtimer" 50 static unsigned long mmdev_mask;
51 static unsigned long mmdev_ratio;
52 static volatile unsigned long *mmdev_timer_addr;
57 unsigned long femtosecs_per_tick = 0;
58 unsigned long freq = 0;
62 SUBDBG(
"MMTIMER Opening %s\n", MMTIMER_FULLNAME );
63 if ( ( mmdev_fd =
open( MMTIMER_FULLNAME, O_RDONLY ) ) == -1 ) {
64 PAPIERROR(
"Failed to open MM timer %s", MMTIMER_FULLNAME );
67 SUBDBG(
"MMTIMER checking if we can mmap" );
68 if ( ioctl( mmdev_fd, MMTIMER_MMAPAVAIL, 0 ) != 1 ) {
69 PAPIERROR(
"mmap of MM timer unavailable" );
72 SUBDBG(
"MMTIMER setting close on EXEC flag\n" );
73 if ( fcntl( mmdev_fd, F_SETFD, FD_CLOEXEC ) == -1 ) {
74 PAPIERROR(
"Failed to fcntl(FD_CLOEXEC) on MM timer FD %d: %s",
75 mmdev_fd, strerror(
errno ) );
78 SUBDBG(
"MMTIMER is on FD %d, getting offset\n", mmdev_fd );
79 if ( (
offset = ioctl( mmdev_fd, MMTIMER_GETOFFSET, 0 ) ) < 0 ) {
80 PAPIERROR(
"Failed to get offset of MM timer" );
83 SUBDBG(
"MMTIMER has offset of %d, getting frequency\n",
offset );
84 if ( ioctl( mmdev_fd, MMTIMER_GETFREQ, &freq ) == -1 ) {
85 PAPIERROR(
"Failed to get frequency of MM timer" );
88 SUBDBG(
"MMTIMER has frequency %lu Mhz\n", freq / 1000000 );
94 SUBDBG(
"MMTIMER has a ratio of %ld to the CPU's clock, getting resolution\n",
96 if ( ioctl( mmdev_fd, MMTIMER_GETRES, &femtosecs_per_tick ) == -1 ) {
97 PAPIERROR(
"Failed to get femtoseconds per tick" );
100 SUBDBG(
"MMTIMER res is %lu femtosecs/tick (10^-15s) or %f Mhz, getting valid bits\n",
101 femtosecs_per_tick, 1.0e9 / (
double ) femtosecs_per_tick );
102 if ( ( result = ioctl( mmdev_fd, MMTIMER_GETBITS, 0 ) ) == -ENOSYS ) {
103 PAPIERROR(
"Failed to get number of bits in MMTIMER" );
106 mmdev_mask = ~( 0xffffffffffffffff << result );
107 SUBDBG(
"MMTIMER has %d valid bits, mask %#16lx, getting mmaped page\n",
108 result, mmdev_mask );
109 if ( ( mmdev_timer_addr =
110 (
unsigned long * ) mmap( 0, getpagesize( ), PROT_READ,
111 MAP_PRIVATE, mmdev_fd,
116 SUBDBG(
"MMTIMER page is at %p, actual address is %p\n",
117 mmdev_timer_addr, mmdev_timer_addr +
offset );
118 mmdev_timer_addr +=
offset;
126 #if defined(__powerpc__) 132 #if defined(__powerpc__) 157 #if defined(HAVE_MMTIMER) 159 static inline long long 164 tmp = *mmdev_timer_addr & mmdev_mask;
165 SUBDBG(
"MMTIMER is %llu, scaled %llu\n",
tmp,
tmp*mmdev_ratio);
175 #elif defined(__ia64__) 178 static inline long long 182 #if defined(__INTEL_COMPILER) 183 tmp = __getReg( _IA64_REG_AR_ITC );
185 __asm__ __volatile__(
"mov %0=ar.itc":
"=r"(
tmp )::
"memory" );
188 case PFMLIB_MONTECITO_PMU:
199 #elif (defined(__i386__)||defined(__x86_64__)) 200 static inline long long 207 asm volatile (
"rdtsc":
"=a" (
a ),
"=d"( d ) );
208 (
ret ) = ( (
long long )
a ) | ( ( (
long long ) d ) << 32 );
212 __asm__ __volatile__(
"rdtsc":
"=A"(
ret ): );
222 #elif defined(__sparc__) 223 static inline long long 226 register unsigned long ret asm(
"g1" );
228 __asm__ __volatile__(
".word 0x83410000" 237 #elif defined(__aarch64__) 238 static inline long long 241 register unsigned long ret;
243 __asm__ __volatile__ (
"isb; mrs %0, cntvct_el0" :
"=r" (
ret));
252 #elif defined(__powerpc__) 278 :
"=r" (result),
"=r" (
dummy));
284 #elif (defined(__arm__) || defined(__mips__) || defined(__hppa__)) 285 static inline long long 292 #elif !defined(HAVE_GETTIMEOFDAY) && !defined(HAVE_CLOCK_GETTIME) 293 #error "No get_cycles support for this architecture. " 305 #if defined(HAVE_GETTIMEOFDAY)||defined(__arm__)||defined(__mips__) 336 #ifdef HAVE_CLOCK_GETTIME_REALTIME_HR 337 syscall( __NR_clock_gettime, CLOCK_REALTIME_HR, &foo );
339 syscall( __NR_clock_gettime, CLOCK_REALTIME, &foo );
341 retval = (
long long ) foo.
tv_sec * (
long long ) 1000000;
359 retval = (
long long )
buffer.tv_sec * (
long long ) 1000000;
394 getrusage( RUSAGE_SELF, &
buffer );
395 SUBDBG(
"user %d system %d\n", (
int )
buffer.ru_utime.tv_sec,
396 (
int )
buffer.ru_stime.tv_sec );
398 * (
long long ) 1000000;
418 SUBDBG(
"user %d system %d\n", (
int )
buffer.tms_utime,
419 (
int )
buffer.tms_stime );
421 1000000 / sysconf( _SC_CLK_TCK ));
440 syscall( __NR_clock_gettime, CLOCK_THREAD_CPUTIME_ID, &foo );
441 retval = (
long long ) foo.
tv_sec * (
long long ) 1000000;
457 long long utime, stime;
458 int rv,
cnt = 0,
i = 0;
463 sprintf(
buf,
"/proc/%d/task/%d/stat", getpid( ),
mygettid( ) );
464 stat_fd =
open(
buf, O_RDONLY );
465 if ( stat_fd == -1 ) {
470 rv =
read( stat_fd,
buf, LINE_MAX *
sizeof (
char ) );
472 if (
errno == EBADF ) {
480 lseek( stat_fd, 0, SEEK_SET );
482 if (rv == LINE_MAX) rv--;
484 SUBDBG(
"Thread stat file is:%s\n",
buf );
485 while ( (
cnt != 13 ) && (
i < rv ) ) {
486 if (
buf[
i] ==
' ' ) {
493 PAPIERROR(
"utime and stime not in thread stat file?" );
498 if ( sscanf(
buf +
i,
"%llu %llu", &utime, &stime ) != 2 ) {
500 PAPIERROR(
"Unable to scan two items from thread stat file at 13th space?");
529 #ifdef HAVE_CLOCK_GETTIME_REALTIME_HR 530 syscall( __NR_clock_gettime, CLOCK_REALTIME_HR, &foo );
532 syscall( __NR_clock_gettime, CLOCK_REALTIME, &foo );
534 retval = (
long long ) foo.
tv_sec * (
long long ) 1000000000;
553 syscall( __NR_clock_gettime, CLOCK_THREAD_CPUTIME_ID, &foo );
554 retval = (
long long ) foo.
tv_sec * (
long long ) 1000000000;
ssize_t read(int fd, void *buf, size_t count)
long long _linux_get_real_cycles(void)
long long _linux_get_virt_usec_gettime(void)
off_t lseek(int fd, off_t offset, int whence)
long long(* get_real_usec)(void)
static int _perfmon2_pfm_pmu_type
static pid_t mygettid(void)
Return codes and api definitions.
long long _linux_get_real_nsec_gettime(void)
__syscall_slong_t tv_nsec
int open(const char *pathname, int flags, mode_t mode)
papi_os_vector_t _papi_os_vector
PAPI_os_info_t _papi_os_info
long long _linux_get_real_usec_cycles(void)
#define SUBDBG(format, args...)
void PAPIERROR(char *format,...)
long long _linux_get_virt_usec_times(void)
int cnt[ctr_pcp_ntv_code_to_info+1]
papi_mdi_t _papi_hwi_system_info
int gettimeofday(void *ptr1, void *ptr2)
long long _linux_get_real_usec_gettime(void)
long long _linux_get_virt_usec_pttimer(void)
long long _linux_get_virt_nsec_gettime(void)
long long _linux_get_virt_usec_rusage(void)
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
long long _linux_get_real_usec_gettimeofday(void)
static double a[MATRIX_SIZE][MATRIX_SIZE]