|
PAPI
5.0.1.0
|

Go to the source code of this file.
Defines | |
| #define | _PATH_SYS_SYSTEM "/sys/devices/system" |
| #define | _PATH_SYS_CPU0 _PATH_SYS_SYSTEM "/cpu/cpu0" |
Functions | |
| static int | _linux_init_locks (void) |
| int | _linux_detect_hypervisor (char *virtual_vendor_name) |
| static char * | search_cpu_info (FILE *f, char *search_str, char *line) |
| static void | decode_vendor_string (char *s, int *vendor) |
| static FILE * | xfopen (const char *path, const char *mode) |
| static FILE * | path_vfopen (const char *mode, const char *path, va_list ap) |
| static int | path_sibling (const char *path,...) |
| static int | path_exist (const char *path,...) |
| int | _linux_get_cpu_info (PAPI_hw_info_t *hwinfo, int *cpuinfo_mhz) |
| int | _linux_get_mhz (int *sys_min_mhz, int *sys_max_mhz) |
| int | _linux_get_system_info (papi_mdi_t *mdi) |
| int | _papi_hwi_init_os (void) |
| int | _linux_detect_nmi_watchdog () |
Variables | |
| PAPI_os_info_t | _papi_os_info |
| volatile unsigned int | _papi_hwd_lock_data [(9+0x2)] |
| static char | pathbuf [PATH_MAX] = "/" |
| papi_os_vector_t | _papi_os_vector |
| #define _PATH_SYS_CPU0 _PATH_SYS_SYSTEM "/cpu/cpu0" |
Definition at line 70 of file linux-common.c.
| #define _PATH_SYS_SYSTEM "/sys/devices/system" |
Definition at line 69 of file linux-common.c.
| int _linux_detect_hypervisor | ( | char * | virtual_vendor_name | ) |
Definition at line 55 of file linux-common.c.
{
int retval=0;
#if defined(__i386__)||defined(__x86_64__)
retval=_x86_detect_hypervisor(virtual_vendor_name);
#else
(void) virtual_vendor_name;
#endif
return retval;
}


| int _linux_detect_nmi_watchdog | ( | ) |
Definition at line 583 of file linux-common.c.
{
int watchdog_detected=0,watchdog_value=0;
FILE *fff;
fff=fopen("/proc/sys/kernel/nmi_watchdog","r");
if (fff!=NULL) {
if (fscanf(fff,"%d",&watchdog_value)==1) {
if (watchdog_value>0) watchdog_detected=1;
}
fclose(fff);
}
return watchdog_detected;
}

| int _linux_get_cpu_info | ( | PAPI_hw_info_t * | hwinfo, |
| int * | cpuinfo_mhz | ||
| ) |
< No error
< A System/C library call failed
Definition at line 171 of file linux-common.c.
{
int tmp, retval = PAPI_OK;
char maxargs[PAPI_HUGE_STR_LEN], *t, *s;
float mhz = 0.0;
FILE *f;
if ( ( f = fopen( "/proc/cpuinfo", "r" ) ) == NULL ) {
PAPIERROR( "fopen(/proc/cpuinfo) errno %d", errno );
return PAPI_ESYS;
}
/* All of this information maybe overwritten by the component */
/* MHZ */
rewind( f );
s = search_cpu_info( f, "clock", maxargs );
if ( !s ) {
rewind( f );
s = search_cpu_info( f, "cpu MHz", maxargs );
}
if ( s ) {
sscanf( s + 1, "%f", &mhz );
}
*cpuinfo_mhz = mhz;
/* Vendor Name and Vendor Code */
rewind( f );
s = search_cpu_info( f, "vendor_id", maxargs );
if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
*t = '\0';
strcpy( hwinfo->vendor_string, s + 2 );
} else {
rewind( f );
s = search_cpu_info( f, "vendor", maxargs );
if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
*t = '\0';
strcpy( hwinfo->vendor_string, s + 2 );
} else {
rewind( f );
s = search_cpu_info( f, "system type", maxargs );
if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
*t = '\0';
s = strtok( s + 2, " " );
strcpy( hwinfo->vendor_string, s );
} else {
rewind( f );
s = search_cpu_info( f, "platform", maxargs );
if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
*t = '\0';
s = strtok( s + 2, " " );
if ( ( strcasecmp( s, "pSeries" ) == 0 ) ||
( strcasecmp( s, "PowerMac" ) == 0 ) ) {
strcpy( hwinfo->vendor_string, "IBM" );
}
} else {
rewind( f );
s = search_cpu_info( f, "CPU implementer", maxargs );
if ( s ) {
strcpy( hwinfo->vendor_string, "ARM" );
}
}
}
}
}
if ( strlen( hwinfo->vendor_string ) ) {
decode_vendor_string( hwinfo->vendor_string, &hwinfo->vendor );
}
/* Revision */
rewind( f );
s = search_cpu_info( f, "stepping", maxargs );
if ( s ) {
sscanf( s + 1, "%d", &tmp );
hwinfo->revision = ( float ) tmp;
hwinfo->cpuid_stepping = tmp;
} else {
rewind( f );
s = search_cpu_info( f, "revision", maxargs );
if ( s ) {
sscanf( s + 1, "%d", &tmp );
hwinfo->revision = ( float ) tmp;
hwinfo->cpuid_stepping = tmp;
}
}
/* Model Name */
rewind( f );
s = search_cpu_info( f, "model name", maxargs );
if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
*t = '\0';
strcpy( hwinfo->model_string, s + 2 );
} else {
rewind( f );
s = search_cpu_info( f, "family", maxargs );
if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
*t = '\0';
strcpy( hwinfo->model_string, s + 2 );
} else {
rewind( f );
s = search_cpu_info( f, "cpu model", maxargs );
if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
*t = '\0';
strtok( s + 2, " " );
s = strtok( NULL, " " );
strcpy( hwinfo->model_string, s );
} else {
rewind( f );
s = search_cpu_info( f, "cpu", maxargs );
if ( s && ( t = strchr( s + 2, '\n' ) ) ) {
*t = '\0';
/* get just the first token */
s = strtok( s + 2, " " );
strcpy( hwinfo->model_string, s );
}
}
}
}
/* Family */
rewind( f );
s = search_cpu_info( f, "family", maxargs );
if ( s ) {
sscanf( s + 1, "%d", &tmp );
hwinfo->cpuid_family = tmp;
} else {
rewind( f );
s = search_cpu_info( f, "cpu family", maxargs );
if ( s ) {
sscanf( s + 1, "%d", &tmp );
hwinfo->cpuid_family = tmp;
}
}
/* CPU Model */
rewind( f );
s = search_cpu_info( f, "model", maxargs );
if ( s ) {
sscanf( s + 1, "%d", &tmp );
hwinfo->model = tmp;
hwinfo->cpuid_model = tmp;
}
/* The following members are set using the same methodology */
/* used in lscpu. */
/* Total number of CPUs */
/* The following line assumes totalcpus was initialized to zero! */
while ( path_exist( _PATH_SYS_SYSTEM "/cpu/cpu%d", hwinfo->totalcpus ) )
hwinfo->totalcpus++;
/* Number of threads per core */
if ( path_exist( _PATH_SYS_CPU0 "/topology/thread_siblings" ) )
hwinfo->threads =
path_sibling( _PATH_SYS_CPU0 "/topology/thread_siblings" );
/* Number of cores per socket */
if ( path_exist( _PATH_SYS_CPU0 "/topology/core_siblings" ) &&
hwinfo->threads > 0 )
hwinfo->cores =
path_sibling( _PATH_SYS_CPU0 "/topology/core_siblings" ) /
hwinfo->threads;
/* Number of sockets */
if ( hwinfo->threads > 0 && hwinfo->cores > 0 )
hwinfo->sockets = hwinfo->ncpu / hwinfo->cores / hwinfo->threads;
/* Number of NUMA nodes */
/* The following line assumes nnodes was initialized to zero! */
while ( path_exist( _PATH_SYS_SYSTEM "/node/node%d", hwinfo->nnodes ) )
hwinfo->nnodes++;
/* Number of CPUs per node */
hwinfo->ncpu =
hwinfo->nnodes >
1 ? hwinfo->totalcpus / hwinfo->nnodes : hwinfo->totalcpus;
#if 0
int *nodecpu;
/* cpumap data is not currently part of the _papi_hw_info struct */
nodecpu = malloc( (unsigned int) hwinfo->nnodes * sizeof(int) );
if ( nodecpu ) {
int i;
for ( i = 0; i < hwinfo->nnodes; ++i ) {
nodecpu[i] = path_sibling(
_PATH_SYS_SYSTEM "/node/node%d/cpumap", i );
}
} else {
PAPIERROR( "malloc failed for variable not currently used" );
}
#endif
/* Fixup missing Megahertz Value */
/* This is missing from cpuinfo on ARM and MIPS */
if (*cpuinfo_mhz < 1.0) {
rewind( f );
s = search_cpu_info( f, "BogoMIPS", maxargs );
if ((!s) || (sscanf( s + 1, "%f", &mhz ) != 1)) {
PAPIERROR("Mhz detection failed. Please edit file %s at line %d.\n",
__FILE__,__LINE__);
}
if (hwinfo->vendor == PAPI_VENDOR_MIPS) {
/* MIPS has 2x clock multiplier */
*cpuinfo_mhz = 2*(((int)mhz)+1);
/* Also update version info on MIPS */
rewind( f );
s = search_cpu_info( f, "cpu model", maxargs );
s = strstr(s+1," V")+2;
strtok(s," ");
sscanf(s, "%f ", &hwinfo->revision );
}
else {
/* In general bogomips is proportional to number of CPUs */
if (hwinfo->totalcpus) {
*cpuinfo_mhz = mhz / hwinfo->totalcpus;
}
}
}
fclose( f );
return retval;
}


| int _linux_get_mhz | ( | int * | sys_min_mhz, |
| int * | sys_max_mhz | ||
| ) |
< Invalid argument
< Invalid argument
< Invalid argument
< Invalid argument
< No error
Definition at line 401 of file linux-common.c.
{
FILE *fff;
int result;
/* Try checking for min MHz */
/* Assume cpu0 exists */
fff=fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_min_freq","r");
if (fff==NULL) return PAPI_EINVAL;
result=fscanf(fff,"%d",sys_min_mhz);
fclose(fff);
if (result!=1) return PAPI_EINVAL;
fff=fopen("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq","r");
if (fff==NULL) return PAPI_EINVAL;
result=fscanf(fff,"%d",sys_max_mhz);
fclose(fff);
if (result!=1) return PAPI_EINVAL;
return PAPI_OK;
}

| int _linux_get_system_info | ( | papi_mdi_t * | mdi | ) |
< A System/C library call failed
< A System/C library call failed
< No error
Definition at line 425 of file linux-common.c.
{
int retval;
char maxargs[PAPI_HUGE_STR_LEN];
pid_t pid;
int cpuinfo_mhz,sys_min_khz,sys_max_khz;
/* Software info */
/* Path and args */
pid = getpid( );
if ( pid < 0 ) {
PAPIERROR( "getpid() returned < 0" );
return PAPI_ESYS;
}
mdi->pid = pid;
sprintf( maxargs, "/proc/%d/exe", ( int ) pid );
if ( readlink( maxargs, mdi->exe_info.fullname, PAPI_HUGE_STR_LEN ) < 0 ) {
PAPIERROR( "readlink(%s) returned < 0", maxargs );
return PAPI_ESYS;
}
/* Careful, basename can modify it's argument */
strcpy( maxargs, mdi->exe_info.fullname );
strcpy( mdi->exe_info.address_info.name, basename( maxargs ) );
SUBDBG( "Executable is %s\n", mdi->exe_info.address_info.name );
SUBDBG( "Full Executable is %s\n", mdi->exe_info.fullname );
/* Executable regions, may require reading /proc/pid/maps file */
retval = _linux_update_shlib_info( mdi );
SUBDBG( "Text: Start %p, End %p, length %d\n",
mdi->exe_info.address_info.text_start,
mdi->exe_info.address_info.text_end,
( int ) ( mdi->exe_info.address_info.text_end -
mdi->exe_info.address_info.text_start ) );
SUBDBG( "Data: Start %p, End %p, length %d\n",
mdi->exe_info.address_info.data_start,
mdi->exe_info.address_info.data_end,
( int ) ( mdi->exe_info.address_info.data_end -
mdi->exe_info.address_info.data_start ) );
SUBDBG( "Bss: Start %p, End %p, length %d\n",
mdi->exe_info.address_info.bss_start,
mdi->exe_info.address_info.bss_end,
( int ) ( mdi->exe_info.address_info.bss_end -
mdi->exe_info.address_info.bss_start ) );
/* PAPI_preload_option information */
strcpy( mdi->preload_info.lib_preload_env, "LD_PRELOAD" );
mdi->preload_info.lib_preload_sep = ' ';
strcpy( mdi->preload_info.lib_dir_env, "LD_LIBRARY_PATH" );
mdi->preload_info.lib_dir_sep = ':';
/* Hardware info */
retval = _linux_get_cpu_info( &mdi->hw_info, &cpuinfo_mhz );
if ( retval )
return retval;
/* Handle MHz */
retval = _linux_get_mhz( &sys_min_khz, &sys_max_khz );
if ( retval ) {
mdi->hw_info.cpu_max_mhz=cpuinfo_mhz;
mdi->hw_info.cpu_min_mhz=cpuinfo_mhz;
/*
mdi->hw_info.mhz=cpuinfo_mhz;
mdi->hw_info.clock_mhz=cpuinfo_mhz;
*/
}
else {
mdi->hw_info.cpu_max_mhz=sys_max_khz/1000;
mdi->hw_info.cpu_min_mhz=sys_min_khz/1000;
/*
mdi->hw_info.mhz=sys_max_khz/1000;
mdi->hw_info.clock_mhz=sys_max_khz/1000;
*/
}
/* Set Up Memory */
retval = _linux_get_memory_info( &mdi->hw_info, mdi->hw_info.model );
if ( retval )
return retval;
SUBDBG( "Found %d %s(%d) %s(%d) CPUs at %d Mhz.\n",
mdi->hw_info.totalcpus,
mdi->hw_info.vendor_string,
mdi->hw_info.vendor,
mdi->hw_info.model_string,
mdi->hw_info.model,
mdi->hw_info.cpu_max_mhz);
/* Get virtualization info */
mdi->hw_info.virtualized=_linux_detect_hypervisor(mdi->hw_info.virtual_vendor_string);
return PAPI_OK;
}


| static int _linux_init_locks | ( | void | ) | [static] |
< Used with setting up array
< No error
Definition at line 38 of file linux-common.c.
{
int i;
for ( i = 0; i < PAPI_MAX_LOCK; i++ ) {
#if defined(USE_PTHREAD_MUTEXES)
pthread_mutex_init(&_papi_hwd_lock_data[i],NULL);
#else
_papi_hwd_lock_data[i] = MUTEX_OPEN;
#endif
}
return PAPI_OK;
}

| int _papi_hwi_init_os | ( | void | ) |
< No error
Definition at line 535 of file linux-common.c.
{
int major=0,minor=0,sub=0;
char *ptr;
struct utsname uname_buffer;
/* Initialize the locks */
_linux_init_locks();
/* Get the kernel info */
uname(&uname_buffer);
SUBDBG("Native kernel version %s\n",uname_buffer.release);
strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN);
#ifdef ASSUME_KERNEL
strncpy(_papi_os_info.version,ASSUME_KERNEL,PAPI_MAX_STR_LEN);
SUBDBG("Assuming kernel version %s\n",_papi_os_info.name);
#else
strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN);
#endif
ptr=strtok(_papi_os_info.version,".");
if (ptr!=NULL) major=atoi(ptr);
ptr=strtok(NULL,".");
if (ptr!=NULL) minor=atoi(ptr);
ptr=strtok(NULL,".");
if (ptr!=NULL) sub=atoi(ptr);
_papi_os_info.os_version=LINUX_VERSION(major,minor,sub);
_papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL;
_papi_os_info.itimer_num = PAPI_INT_ITIMER;
_papi_os_info.itimer_ns = PAPI_INT_MPX_DEF_US * 1000;
_papi_os_info.itimer_res_ns = 1;
_papi_os_info.clock_ticks = sysconf( _SC_CLK_TCK );
/* Get Linux-specific system info */
_linux_get_system_info( &_papi_hwi_system_info );
return PAPI_OK;
}

| static void decode_vendor_string | ( | char * | s, |
| int * | vendor | ||
| ) | [static] |
Definition at line 94 of file linux-common.c.
{
if ( strcasecmp( s, "GenuineIntel" ) == 0 )
*vendor = PAPI_VENDOR_INTEL;
else if ( ( strcasecmp( s, "AMD" ) == 0 ) ||
( strcasecmp( s, "AuthenticAMD" ) == 0 ) )
*vendor = PAPI_VENDOR_AMD;
else if ( strcasecmp( s, "IBM" ) == 0 )
*vendor = PAPI_VENDOR_IBM;
else if ( strcasecmp( s, "Cray" ) == 0 )
*vendor = PAPI_VENDOR_CRAY;
else if ( strcasecmp( s, "ARM" ) == 0 )
*vendor = PAPI_VENDOR_ARM;
else if ( strcasecmp( s, "MIPS" ) == 0 )
*vendor = PAPI_VENDOR_MIPS;
else if ( strcasecmp( s, "SiCortex" ) == 0 )
*vendor = PAPI_VENDOR_MIPS;
else
*vendor = PAPI_VENDOR_UNKNOWN;
}

| static int path_exist | ( | const char * | path, |
| ... | |||
| ) | [static] |
Definition at line 161 of file linux-common.c.
{
va_list ap;
va_start( ap, path );
vsnprintf( pathbuf, sizeof ( pathbuf ), path, ap );
va_end( ap );
return access( pathbuf, F_OK ) == 0;
}

| static int path_sibling | ( | const char * | path, |
| ... | |||
| ) | [static] |
Definition at line 133 of file linux-common.c.
{
int c;
long n;
int result = 0;
char s[2];
FILE *fp;
va_list ap;
va_start( ap, path );
fp = path_vfopen( "r", path, ap );
va_end( ap );
while ( ( c = fgetc( fp ) ) != EOF ) {
if ( isxdigit( c ) ) {
s[0] = ( char ) c;
s[1] = '\0';
for ( n = strtol( s, NULL, 16 ); n > 0; n /= 2 ) {
if ( n % 2 )
result++;
}
}
}
fclose( fp );
return result;
}


| static FILE* path_vfopen | ( | const char * | mode, |
| const char * | path, | ||
| va_list | ap | ||
| ) | [static] |
| static char* search_cpu_info | ( | FILE * | f, |
| char * | search_str, | ||
| char * | line | ||
| ) | [static] |
Definition at line 76 of file linux-common.c.
{
/* This function courtesy of Rudolph Berrendorf! */
/* See the home page for the German version of PAPI. */
char *s;
while ( fgets( line, 256, f ) != NULL ) {
if ( strstr( line, search_str ) != NULL ) {
/* ignore all characters in line up to : */
for ( s = line; *s && ( *s != ':' ); ++s );
if ( *s )
return s;
}
}
return NULL;
}

| static FILE* xfopen | ( | const char * | path, |
| const char * | mode | ||
| ) | [static] |
| volatile unsigned int _papi_hwd_lock_data[(9+0x2)] |
Definition at line 34 of file linux-common.c.
Definition at line 27 of file linux-common.c.
Definition at line 599 of file linux-common.c.
Definition at line 72 of file linux-common.c.