Blame src/solaris-common.c

Packit 577717
#include "papi.h"
Packit 577717
#include "papi_internal.h"
Packit 577717
#include "papi_vector.h"
Packit 577717
#include "papi_memory.h"
Packit 577717
Packit 577717
#include "solaris-common.h"
Packit 577717
Packit 577717
#include <sys/utsname.h>
Packit 577717
Packit 577717
Packit 577717
#if 0
Packit 577717
/* once the bug in dladdr is fixed by SUN, (now dladdr caused deadlock when
Packit 577717
   used with pthreads) this function can be used again */
Packit 577717
int
Packit 577717
_solaris_update_shlib_info( papi_mdi_t *mdi )
Packit 577717
{
Packit 577717
	char fname[80], name[PAPI_HUGE_STR_LEN];
Packit 577717
	prmap_t newp;
Packit 577717
	int count, t_index;
Packit 577717
	FILE *map_f;
Packit 577717
	void *vaddr;
Packit 577717
	Dl_info dlip;
Packit 577717
	PAPI_address_map_t *tmp = NULL;
Packit 577717
Packit 577717
	sprintf( fname, "/proc/%d/map", getpid(  ) );
Packit 577717
	map_f = fopen( fname, "r" );
Packit 577717
	if ( !map_f ) {
Packit 577717
		PAPIERROR( "fopen(%s) returned < 0", fname );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
Packit 577717
	/* count the entries we need */
Packit 577717
	count = 0;
Packit 577717
	t_index = 0;
Packit 577717
	while ( fread( &newp, sizeof ( prmap_t ), 1, map_f ) > 0 ) {
Packit 577717
		vaddr = ( void * ) ( 1 + ( newp.pr_vaddr ) );	// map base address 
Packit 577717
		if ( dladdr( vaddr, &dlip ) > 0 ) {
Packit 577717
			count++;
Packit 577717
			if ( ( newp.pr_mflags & MA_EXEC ) && ( newp.pr_mflags & MA_READ ) ) {
Packit 577717
				if ( !( newp.pr_mflags & MA_WRITE ) )
Packit 577717
					t_index++;
Packit 577717
			}
Packit 577717
			strcpy( name, dlip.dli_fname );
Packit 577717
			if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name,
Packit 577717
						 basename( name ) ) == 0 ) {
Packit 577717
				if ( ( newp.pr_mflags & MA_EXEC ) &&
Packit 577717
					 ( newp.pr_mflags & MA_READ ) ) {
Packit 577717
					if ( !( newp.pr_mflags & MA_WRITE ) ) {
Packit 577717
						_papi_hwi_system_info.exe_info.address_info.text_start =
Packit 577717
							( caddr_t ) newp.pr_vaddr;
Packit 577717
						_papi_hwi_system_info.exe_info.address_info.text_end =
Packit 577717
							( caddr_t ) ( newp.pr_vaddr + newp.pr_size );
Packit 577717
					} else {
Packit 577717
						_papi_hwi_system_info.exe_info.address_info.data_start =
Packit 577717
							( caddr_t ) newp.pr_vaddr;
Packit 577717
						_papi_hwi_system_info.exe_info.address_info.data_end =
Packit 577717
							( caddr_t ) ( newp.pr_vaddr + newp.pr_size );
Packit 577717
					}
Packit 577717
				}
Packit 577717
			}
Packit 577717
		}
Packit 577717
Packit 577717
	}
Packit 577717
	rewind( map_f );
Packit 577717
	tmp =
Packit 577717
		( PAPI_address_map_t * ) papi_calloc( t_index - 1,
Packit 577717
											  sizeof ( PAPI_address_map_t ) );
Packit 577717
Packit 577717
	if ( tmp == NULL ) {
Packit 577717
		PAPIERROR( "Error allocating shared library address map" );
Packit 577717
		return ( PAPI_ENOMEM );
Packit 577717
	}
Packit 577717
	t_index = -1;
Packit 577717
	while ( fread( &newp, sizeof ( prmap_t ), 1, map_f ) > 0 ) {
Packit 577717
		vaddr = ( void * ) ( 1 + ( newp.pr_vaddr ) );	// map base address
Packit 577717
		if ( dladdr( vaddr, &dlip ) > 0 ) {	// valid name
Packit 577717
			strcpy( name, dlip.dli_fname );
Packit 577717
			if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name,
Packit 577717
						 basename( name ) ) == 0 )
Packit 577717
				continue;
Packit 577717
			if ( ( newp.pr_mflags & MA_EXEC ) && ( newp.pr_mflags & MA_READ ) ) {
Packit 577717
				if ( !( newp.pr_mflags & MA_WRITE ) ) {
Packit 577717
					t_index++;
Packit 577717
					tmp[t_index].text_start = ( caddr_t ) newp.pr_vaddr;
Packit 577717
					tmp[t_index].text_end =
Packit 577717
						( caddr_t ) ( newp.pr_vaddr + newp.pr_size );
Packit 577717
					strncpy( tmp[t_index].name, dlip.dli_fname,
Packit 577717
							 PAPI_HUGE_STR_LEN - 1 );
Packit 577717
					tmp[t_index].name[PAPI_HUGE_STR_LEN - 1] = '\0';
Packit 577717
				} else {
Packit 577717
					if ( t_index < 0 )
Packit 577717
						continue;
Packit 577717
					tmp[t_index].data_start = ( caddr_t ) newp.pr_vaddr;
Packit 577717
					tmp[t_index].data_end =
Packit 577717
						( caddr_t ) ( newp.pr_vaddr + newp.pr_size );
Packit 577717
				}
Packit 577717
			}
Packit 577717
		}
Packit 577717
	}
Packit 577717
Packit 577717
	fclose( map_f );
Packit 577717
Packit 577717
	if ( _papi_hwi_system_info.shlib_info.map )
Packit 577717
		papi_free( _papi_hwi_system_info.shlib_info.map );
Packit 577717
	_papi_hwi_system_info.shlib_info.map = tmp;
Packit 577717
	_papi_hwi_system_info.shlib_info.count = t_index + 1;
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
#endif
Packit 577717
Packit 577717
Packit 577717
int
Packit 577717
_papi_hwi_init_os(void) {
Packit 577717
Packit 577717
  struct utsname uname_buffer;
Packit 577717
Packit 577717
  uname(&uname_buffer);
Packit 577717
Packit 577717
  strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN);
Packit 577717
Packit 577717
  strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN);
Packit 577717
Packit 577717
  _papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL;
Packit 577717
  _papi_os_info.itimer_num = PAPI_INT_ITIMER;
Packit 577717
  _papi_os_info.itimer_ns = PAPI_INT_MPX_DEF_US * 1000;
Packit 577717
  _papi_os_info.itimer_res_ns = 1;
Packit 577717
Packit 577717
  return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
#if 0
Packit 577717
int
Packit 577717
_ultra_hwd_update_shlib_info( papi_mdi_t *mdi )
Packit 577717
{
Packit 577717
	/*??? system call takes very long */
Packit 577717
Packit 577717
	char cmd_line[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], fname[L_tmpnam];
Packit 577717
	char line[256];
Packit 577717
	char address[16], size[10], flags[64], objname[256];
Packit 577717
	PAPI_address_map_t *tmp = NULL;
Packit 577717
Packit 577717
	FILE *f = NULL;
Packit 577717
	int t_index = 0, i;
Packit 577717
	struct map_record
Packit 577717
	{
Packit 577717
		long address;
Packit 577717
		int size;
Packit 577717
		int flags;
Packit 577717
		char objname[256];
Packit 577717
		struct map_record *next;
Packit 577717
	} *tmpr, *head, *curr;
Packit 577717
Packit 577717
	tmpnam( fname );
Packit 577717
	SUBDBG( "Temporary name %s\n", fname );
Packit 577717
Packit 577717
	sprintf( cmd_line, "/bin/pmap %d > %s", ( int ) getpid(  ), fname );
Packit 577717
	if ( system( cmd_line ) != 0 ) {
Packit 577717
		PAPIERROR( "Could not run %s to get shared library address map",
Packit 577717
				   cmd_line );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
Packit 577717
	f = fopen( fname, "r" );
Packit 577717
	if ( f == NULL ) {
Packit 577717
		PAPIERROR( "fopen(%s) returned < 0", fname );
Packit 577717
		remove( fname );
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
Packit 577717
	/* ignore the first line */
Packit 577717
	fgets( line, 256, f );
Packit 577717
	head = curr = NULL;
Packit 577717
	while ( fgets( line, 256, f ) != NULL ) {
Packit 577717
		/* discard the last line */
Packit 577717
		if ( strncmp( line, " total", 6 ) != 0 ) {
Packit 577717
			sscanf( line, "%s %s %s %s", address, size, flags, objname );
Packit 577717
			if ( objname[0] == '/' ) {
Packit 577717
				tmpr =
Packit 577717
					( struct map_record * )
Packit 577717
					papi_malloc( sizeof ( struct map_record ) );
Packit 577717
				if ( tmpr == NULL )
Packit 577717
					return ( -1 );
Packit 577717
				tmpr->next = NULL;
Packit 577717
				if ( curr ) {
Packit 577717
					curr->next = tmpr;
Packit 577717
					curr = tmpr;
Packit 577717
				}
Packit 577717
				if ( head == NULL ) {
Packit 577717
					curr = head = tmpr;
Packit 577717
				}
Packit 577717
Packit 577717
				SUBDBG( "%s\n", objname );
Packit 577717
Packit 577717
				if ( ( strstr( flags, "read" ) && strstr( flags, "exec" ) ) ||
Packit 577717
					 ( strstr( flags, "r" ) && strstr( flags, "x" ) ) ) {
Packit 577717
					if ( !( strstr( flags, "write" ) || strstr( flags, "w" ) ) ) {	/* text segment */
Packit 577717
						t_index++;
Packit 577717
						tmpr->flags = 1;
Packit 577717
					} else {
Packit 577717
						tmpr->flags = 0;
Packit 577717
					}
Packit 577717
					sscanf( address, "%lx", &tmpr->address );
Packit 577717
					sscanf( size, "%d", &tmpr->size );
Packit 577717
					tmpr->size *= 1024;
Packit 577717
					strcpy( tmpr->objname, objname );
Packit 577717
				}
Packit 577717
Packit 577717
			}
Packit 577717
Packit 577717
		}
Packit 577717
	}
Packit 577717
	tmp =
Packit 577717
		( PAPI_address_map_t * ) papi_calloc( t_index - 1,
Packit 577717
											  sizeof ( PAPI_address_map_t ) );
Packit 577717
Packit 577717
	if ( tmp == NULL ) {
Packit 577717
		PAPIERROR( "Error allocating shared library address map" );
Packit 577717
		return ( PAPI_ENOMEM );
Packit 577717
	}
Packit 577717
Packit 577717
	t_index = -1;
Packit 577717
	tmpr = curr = head;
Packit 577717
	i = 0;
Packit 577717
	while ( curr != NULL ) {
Packit 577717
		if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name,
Packit 577717
					 basename( curr->objname ) ) == 0 ) {
Packit 577717
			if ( curr->flags ) {
Packit 577717
				_papi_hwi_system_info.exe_info.address_info.text_start =
Packit 577717
					( caddr_t ) curr->address;
Packit 577717
				_papi_hwi_system_info.exe_info.address_info.text_end =
Packit 577717
					( caddr_t ) ( curr->address + curr->size );
Packit 577717
			} else {
Packit 577717
				_papi_hwi_system_info.exe_info.address_info.data_start =
Packit 577717
					( caddr_t ) curr->address;
Packit 577717
				_papi_hwi_system_info.exe_info.address_info.data_end =
Packit 577717
					( caddr_t ) ( curr->address + curr->size );
Packit 577717
			}
Packit 577717
		} else {
Packit 577717
			if ( curr->flags ) {
Packit 577717
				t_index++;
Packit 577717
				tmp[t_index].text_start = ( caddr_t ) curr->address;
Packit 577717
				tmp[t_index].text_end =
Packit 577717
					( caddr_t ) ( curr->address + curr->size );
Packit 577717
				strncpy( tmp[t_index].name, curr->objname,
Packit 577717
						 PAPI_HUGE_STR_LEN - 1 );
Packit 577717
				tmp[t_index].name[PAPI_HUGE_STR_LEN - 1] = '\0';
Packit 577717
			} else {
Packit 577717
				if ( t_index < 0 )
Packit 577717
					continue;
Packit 577717
				tmp[t_index].data_start = ( caddr_t ) curr->address;
Packit 577717
				tmp[t_index].data_end =
Packit 577717
					( caddr_t ) ( curr->address + curr->size );
Packit 577717
			}
Packit 577717
		}
Packit 577717
		tmpr = curr->next;
Packit 577717
		/* free the temporary allocated memory */
Packit 577717
		papi_free( curr );
Packit 577717
		curr = tmpr;
Packit 577717
	}						 /* end of while */
Packit 577717
Packit 577717
	remove( fname );
Packit 577717
	fclose( f );
Packit 577717
	if ( _papi_hwi_system_info.shlib_info.map )
Packit 577717
		papi_free( _papi_hwi_system_info.shlib_info.map );
Packit 577717
	_papi_hwi_system_info.shlib_info.map = tmp;
Packit 577717
	_papi_hwi_system_info.shlib_info.count = t_index + 1;
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
Packit 577717
}
Packit 577717
Packit 577717
#endif
Packit 577717
Packit 577717
/* From niagara2 code */
Packit 577717
int
Packit 577717
_solaris_update_shlib_info( papi_mdi_t *mdi )
Packit 577717
{
Packit 577717
	char *file = "/proc/self/map";
Packit 577717
	char *resolve_pattern = "/proc/self/path/%s";
Packit 577717
Packit 577717
	char lastobject[PRMAPSZ];
Packit 577717
	char link[PAPI_HUGE_STR_LEN];
Packit 577717
	char path[PAPI_HUGE_STR_LEN];
Packit 577717
Packit 577717
	prmap_t mapping;
Packit 577717
Packit 577717
	int fd, count = 0, total = 0, position = -1, first = 1;
Packit 577717
	caddr_t t_min, t_max, d_min, d_max;
Packit 577717
Packit 577717
	PAPI_address_map_t *pam, *cur;
Packit 577717
Packit 577717
#ifdef DEBUG
Packit 577717
	SUBDBG( "ENTERING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit 577717
			__LINE__ );
Packit 577717
#endif
Packit 577717
Packit 577717
	fd = open( file, O_RDONLY );
Packit 577717
Packit 577717
	if ( fd == -1 ) {
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
Packit 577717
	memset( lastobject, 0, PRMAPSZ );
Packit 577717
Packit 577717
#ifdef DEBUG
Packit 577717
	SUBDBG( " -> %s: Preprocessing memory maps from procfs\n", __func__ );
Packit 577717
#endif
Packit 577717
Packit 577717
	/* Search through the list of mappings in order to identify a) how many
Packit 577717
	   mappings are available and b) how many unique mappings are available. */
Packit 577717
	while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
Packit 577717
#ifdef DEBUG
Packit 577717
		SUBDBG( " -> %s: Found a new memory map entry\n", __func__ );
Packit 577717
#endif
Packit 577717
		/* Another entry found, just the total count of entries. */
Packit 577717
		total++;
Packit 577717
Packit 577717
		/* Is the mapping accessible and not anonymous? */
Packit 577717
		if ( mapping.pr_mflags & ( MA_READ | MA_WRITE | MA_EXEC ) &&
Packit 577717
			 !( mapping.pr_mflags & MA_ANON ) ) {
Packit 577717
			/* Test if a new library has been found. If a new library has been
Packit 577717
			   found a new entry needs to be counted. */
Packit 577717
			if ( strcmp( lastobject, mapping.pr_mapname ) != 0 ) {
Packit 577717
				strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
Packit 577717
				count++;
Packit 577717
Packit 577717
#ifdef DEBUG
Packit 577717
				SUBDBG( " -> %s: Memory mapping entry valid for %s\n", __func__,
Packit 577717
						mapping.pr_mapname );
Packit 577717
#endif
Packit 577717
			}
Packit 577717
		}
Packit 577717
	}
Packit 577717
#ifdef DEBUG
Packit 577717
	SUBDBG( " -> %s: Preprocessing done, starting to analyze\n", __func__ );
Packit 577717
#endif
Packit 577717
Packit 577717
Packit 577717
	/* Start from the beginning, now fill in the found mappings */
Packit 577717
	if ( lseek( fd, 0, SEEK_SET ) == -1 ) {
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
Packit 577717
	memset( lastobject, 0, PRMAPSZ );
Packit 577717
Packit 577717
	/* Allocate memory */
Packit 577717
	pam =
Packit 577717
		( PAPI_address_map_t * ) papi_calloc( count,
Packit 577717
											  sizeof ( PAPI_address_map_t ) );
Packit 577717
Packit 577717
	while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
Packit 577717
Packit 577717
		if ( mapping.pr_mflags & MA_ANON ) {
Packit 577717
#ifdef DEBUG
Packit 577717
			SUBDBG
Packit 577717
				( " -> %s: Anonymous mapping (MA_ANON) found for %s, skipping\n",
Packit 577717
				  __func__, mapping.pr_mapname );
Packit 577717
#endif
Packit 577717
			continue;
Packit 577717
		}
Packit 577717
Packit 577717
		/* Check for a new entry */
Packit 577717
		if ( strcmp( mapping.pr_mapname, lastobject ) != 0 ) {
Packit 577717
#ifdef DEBUG
Packit 577717
			SUBDBG( " -> %s: Analyzing mapping for %s\n", __func__,
Packit 577717
					mapping.pr_mapname );
Packit 577717
#endif
Packit 577717
			cur = &( pam[++position] );
Packit 577717
			strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
Packit 577717
			snprintf( link, PAPI_HUGE_STR_LEN, resolve_pattern, lastobject );
Packit 577717
			memset( path, 0, PAPI_HUGE_STR_LEN );
Packit 577717
			readlink( link, path, PAPI_HUGE_STR_LEN );
Packit 577717
			strncpy( cur->name, path, PAPI_HUGE_STR_LEN );
Packit 577717
#ifdef DEBUG
Packit 577717
			SUBDBG( " -> %s: Resolved name for %s: %s\n", __func__,
Packit 577717
					mapping.pr_mapname, cur->name );
Packit 577717
#endif
Packit 577717
		}
Packit 577717
Packit 577717
		if ( mapping.pr_mflags & MA_READ ) {
Packit 577717
			/* Data (MA_WRITE) or text (MA_READ) segment? */
Packit 577717
			if ( mapping.pr_mflags & MA_WRITE ) {
Packit 577717
				cur->data_start = ( caddr_t ) mapping.pr_vaddr;
Packit 577717
				cur->data_end =
Packit 577717
					( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );
Packit 577717
Packit 577717
				if ( strcmp
Packit 577717
					 ( cur->name,
Packit 577717
					   _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
Packit 577717
					_papi_hwi_system_info.exe_info.address_info.data_start =
Packit 577717
						cur->data_start;
Packit 577717
					_papi_hwi_system_info.exe_info.address_info.data_end =
Packit 577717
						cur->data_end;
Packit 577717
				}
Packit 577717
Packit 577717
				if ( first )
Packit 577717
					d_min = cur->data_start;
Packit 577717
				if ( first )
Packit 577717
					d_max = cur->data_end;
Packit 577717
Packit 577717
				if ( cur->data_start < d_min ) {
Packit 577717
					d_min = cur->data_start;
Packit 577717
				}
Packit 577717
Packit 577717
				if ( cur->data_end > d_max ) {
Packit 577717
					d_max = cur->data_end;
Packit 577717
				}
Packit 577717
			} else if ( mapping.pr_mflags & MA_EXEC ) {
Packit 577717
				cur->text_start = ( caddr_t ) mapping.pr_vaddr;
Packit 577717
				cur->text_end =
Packit 577717
					( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );
Packit 577717
Packit 577717
				if ( strcmp
Packit 577717
					 ( cur->name,
Packit 577717
					   _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
Packit 577717
					_papi_hwi_system_info.exe_info.address_info.text_start =
Packit 577717
						cur->text_start;
Packit 577717
					_papi_hwi_system_info.exe_info.address_info.text_end =
Packit 577717
						cur->text_end;
Packit 577717
				}
Packit 577717
Packit 577717
				if ( first )
Packit 577717
					t_min = cur->text_start;
Packit 577717
				if ( first )
Packit 577717
					t_max = cur->text_end;
Packit 577717
Packit 577717
				if ( cur->text_start < t_min ) {
Packit 577717
					t_min = cur->text_start;
Packit 577717
				}
Packit 577717
Packit 577717
				if ( cur->text_end > t_max ) {
Packit 577717
					t_max = cur->text_end;
Packit 577717
				}
Packit 577717
			}
Packit 577717
		}
Packit 577717
Packit 577717
		first = 0;
Packit 577717
	}
Packit 577717
Packit 577717
	close( fd );
Packit 577717
Packit 577717
	/* During the walk of shared objects the upper and lower bound of the
Packit 577717
	   segments could be discovered. The bounds are stored in the PAPI info
Packit 577717
	   structure. The information is important for the profiling functions of
Packit 577717
	   PAPI. */
Packit 577717
Packit 577717
/* This variant would pass the addresses of all text and data segments 
Packit 577717
  _papi_hwi_system_info.exe_info.address_info.text_start = t_min;
Packit 577717
  _papi_hwi_system_info.exe_info.address_info.text_end = t_max;
Packit 577717
  _papi_hwi_system_info.exe_info.address_info.data_start = d_min;
Packit 577717
  _papi_hwi_system_info.exe_info.address_info.data_end = d_max;
Packit 577717
*/
Packit 577717
Packit 577717
#ifdef DEBUG
Packit 577717
	SUBDBG( " -> %s: Analysis of memory maps done, results:\n", __func__ );
Packit 577717
	SUBDBG( " -> %s: text_start=%#x, text_end=%#x, text_size=%lld\n", __func__,
Packit 577717
			_papi_hwi_system_info.exe_info.address_info.text_start,
Packit 577717
			_papi_hwi_system_info.exe_info.address_info.text_end,
Packit 577717
			_papi_hwi_system_info.exe_info.address_info.text_end
Packit 577717
			- _papi_hwi_system_info.exe_info.address_info.text_start );
Packit 577717
	SUBDBG( " -> %s: data_start=%#x, data_end=%#x, data_size=%lld\n", __func__,
Packit 577717
			_papi_hwi_system_info.exe_info.address_info.data_start,
Packit 577717
			_papi_hwi_system_info.exe_info.address_info.data_end,
Packit 577717
			_papi_hwi_system_info.exe_info.address_info.data_end
Packit 577717
			- _papi_hwi_system_info.exe_info.address_info.data_start );
Packit 577717
#endif
Packit 577717
Packit 577717
	/* Store the map read and the total count of shlibs found */
Packit 577717
	_papi_hwi_system_info.shlib_info.map = pam;
Packit 577717
	_papi_hwi_system_info.shlib_info.count = count;
Packit 577717
Packit 577717
#ifdef DEBUG
Packit 577717
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit 577717
			__LINE__ );
Packit 577717
#endif
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
#if 0
Packit 577717
int
Packit 577717
_niagara2_get_system_info( papi_mdi_t *mdi )
Packit 577717
{
Packit 577717
	// Used for evaluating return values
Packit 577717
	int retval = 0;
Packit 577717
	// Check for process settings
Packit 577717
	pstatus_t *proc_status;
Packit 577717
	psinfo_t *proc_info;
Packit 577717
	// Used for string truncating
Packit 577717
	char *c_ptr;
Packit 577717
	// For retrieving the executable full name
Packit 577717
	char exec_name[PAPI_HUGE_STR_LEN];
Packit 577717
	// For retrieving processor information
Packit 577717
	__sol_processor_information_t cpus;
Packit 577717
Packit 577717
#ifdef DEBUG
Packit 577717
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
Packit 577717
			__LINE__ );
Packit 577717
#endif
Packit 577717
Packit 577717
	/* Get and set pid */
Packit 577717
	pid = getpid(  );
Packit 577717
Packit 577717
	/* Check for microstate accounting */
Packit 577717
	proc_status = __sol_get_proc_status( pid );
Packit 577717
Packit 577717
	if ( proc_status->pr_flags & PR_MSACCT == 0 ||
Packit 577717
		 proc_status->pr_flags & PR_MSFORK == 0 ) {
Packit 577717
		/* Solaris 10 should have microstate accounting always activated */
Packit 577717
		return PAPI_ECMP;
Packit 577717
	}
Packit 577717
Packit 577717
	/* Fill _papi_hwi_system_info.exe_info.fullname */
Packit 577717
	proc_info = __sol_get_proc_info( pid );
Packit 577717
Packit 577717
	// If there are arguments, trim the string to the executable name.
Packit 577717
	if ( proc_info->pr_argc > 1 ) {
Packit 577717
		c_ptr = strchr( proc_info->pr_psargs, ' ' );
Packit 577717
		if ( c_ptr != NULL )
Packit 577717
			c_ptr = '\0';
Packit 577717
	}
Packit 577717
Packit 577717
	/* If the path can be qualified, use the full path, otherwise the trimmed
Packit 577717
	   name. */
Packit 577717
	if ( realpath( proc_info->pr_psargs, exec_name ) != NULL ) {
Packit 577717
		strncpy( _papi_hwi_system_info.exe_info.fullname, exec_name,
Packit 577717
				 PAPI_HUGE_STR_LEN );
Packit 577717
	} else {
Packit 577717
		strncpy( _papi_hwi_system_info.exe_info.fullname, proc_info->pr_psargs,
Packit 577717
				 PAPI_HUGE_STR_LEN );
Packit 577717
	}
Packit 577717
Packit 577717
	/* Fill _papi_hwi_system_info.exe_info.address_info */
Packit 577717
	// Taken from the old component
Packit 577717
	strncpy( _papi_hwi_system_info.exe_info.address_info.name,
Packit 577717
			 basename( _papi_hwi_system_info.exe_info.fullname ),
Packit 577717
			 PAPI_HUGE_STR_LEN );
Packit 577717
	__CHECK_ERR_PAPI( _niagara2_update_shlib_info( &_papi_hwi_system_info ) );
Packit 577717
Packit 577717
	/* Fill _papi_hwi_system_info.hw_info */
Packit 577717
Packit 577717
	// Taken from the old component
Packit 577717
	_papi_hwi_system_info.hw_info.ncpu = sysconf( _SC_NPROCESSORS_ONLN );
Packit 577717
	_papi_hwi_system_info.hw_info.nnodes = 1;
Packit 577717
	_papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_SUN;
Packit 577717
	strcpy( _papi_hwi_system_info.hw_info.vendor_string, "SUN" );
Packit 577717
	_papi_hwi_system_info.hw_info.totalcpus = sysconf( _SC_NPROCESSORS_CONF );
Packit 577717
	_papi_hwi_system_info.hw_info.model = 1;
Packit 577717
	strcpy( _papi_hwi_system_info.hw_info.model_string, cpc_cciname( cpc ) );
Packit 577717
Packit 577717
	/* The field sparc-version is no longer in prtconf -pv */
Packit 577717
	_papi_hwi_system_info.hw_info.revision = 1;
Packit 577717
Packit 577717
	/* Clock speed */
Packit 577717
	_papi_hwi_system_info.hw_info.mhz = ( float ) __sol_get_processor_clock(  );
Packit 577717
	_papi_hwi_system_info.hw_info.clock_mhz = __sol_get_processor_clock(  );
Packit 577717
	_papi_hwi_system_info.hw_info.cpu_max_mhz = __sol_get_processor_clock(  );
Packit 577717
	_papi_hwi_system_info.hw_info.cpu_min_mhz = __sol_get_processor_clock(  );
Packit 577717
Packit 577717
	/* Fill _niagara2_vector.cmp_info.mem_hierarchy */
Packit 577717
Packit 577717
	_niagara2_get_memory_info( &_papi_hwi_system_info.hw_info, 0 );
Packit 577717
Packit 577717
	/* Fill _papi_hwi_system_info.sub_info */
Packit 577717
	strcpy( _niagara2_vector.cmp_info.name, "SunNiagara2" );
Packit 577717
	strcpy( _niagara2_vector.cmp_info.version, "ALPHA" );
Packit 577717
	strcpy( _niagara2_vector.cmp_info.support_version, "libcpc2" );
Packit 577717
	strcpy( _niagara2_vector.cmp_info.kernel_version, "libcpc2" );
Packit 577717
Packit 577717
	/* libcpc2 uses SIGEMT using real hardware signals, no sw emu */
Packit 577717
Packit 577717
#ifdef DEBUG
Packit 577717
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
Packit 577717
			__LINE__ );
Packit 577717
#endif
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
#endif
Packit 577717
Packit 577717
int
Packit 577717
_solaris_get_system_info( papi_mdi_t *mdi )
Packit 577717
{
Packit 577717
	int retval;
Packit 577717
	pid_t pid;
Packit 577717
	char maxargs[PAPI_MAX_STR_LEN] = "<none>";
Packit 577717
	psinfo_t psi;
Packit 577717
	int fd;
Packit 577717
	int hz, version;
Packit 577717
	char cpuname[PAPI_MAX_STR_LEN], pname[PAPI_HUGE_STR_LEN];
Packit 577717
Packit 577717
	/* Check counter access */
Packit 577717
Packit 577717
	if ( cpc_version( CPC_VER_CURRENT ) != CPC_VER_CURRENT )
Packit 577717
		return PAPI_ECMP;
Packit 577717
	SUBDBG( "CPC version %d successfully opened\n", CPC_VER_CURRENT );
Packit 577717
Packit 577717
	if ( cpc_access(  ) == -1 )
Packit 577717
		return PAPI_ECMP;
Packit 577717
Packit 577717
	/* Global variable cpuver */
Packit 577717
Packit 577717
	cpuver = cpc_getcpuver(  );
Packit 577717
	SUBDBG( "Got %d from cpc_getcpuver()\n", cpuver );
Packit 577717
	if ( cpuver == -1 )
Packit 577717
		return PAPI_ECMP;
Packit 577717
Packit 577717
#ifdef DEBUG
Packit 577717
	{
Packit 577717
		if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
Packit 577717
			const char *name;
Packit 577717
			int i;
Packit 577717
Packit 577717
			name = cpc_getcpuref( cpuver );
Packit 577717
			if ( name ) {
Packit 577717
				SUBDBG( "CPC CPU reference: %s\n", name );
Packit 577717
			}
Packit 577717
			else {
Packit 577717
				SUBDBG( "Could not get a CPC CPU reference\n" );
Packit 577717
			}
Packit 577717
Packit 577717
			for ( i = 0; i < cpc_getnpic( cpuver ); i++ ) {
Packit 577717
				SUBDBG( "\n%6s %-40s %8s\n", "Reg", "Symbolic name", "Code" );
Packit 577717
				cpc_walk_names( cpuver, i, "%6d %-40s %02x\n",
Packit 577717
								print_walk_names );
Packit 577717
			}
Packit 577717
			SUBDBG( "\n" );
Packit 577717
		}
Packit 577717
	}
Packit 577717
#endif
Packit 577717
Packit 577717
Packit 577717
	/* Initialize other globals */
Packit 577717
Packit 577717
	if ( ( retval = build_tables(  ) ) != PAPI_OK )
Packit 577717
		return retval;
Packit 577717
Packit 577717
	preset_search_map = preset_table;
Packit 577717
	if ( cpuver <= CPC_ULTRA2 ) {
Packit 577717
		SUBDBG( "cpuver (==%d) <= CPC_ULTRA2 (==%d)\n", cpuver, CPC_ULTRA2 );
Packit 577717
		pcr_shift[0] = CPC_ULTRA_PCR_PIC0_SHIFT;
Packit 577717
		pcr_shift[1] = CPC_ULTRA_PCR_PIC1_SHIFT;
Packit 577717
	} else if ( cpuver <= LASTULTRA3 ) {
Packit 577717
		SUBDBG( "cpuver (==%d) <= CPC_ULTRA3x (==%d)\n", cpuver, LASTULTRA3 );
Packit 577717
		pcr_shift[0] = CPC_ULTRA_PCR_PIC0_SHIFT;
Packit 577717
		pcr_shift[1] = CPC_ULTRA_PCR_PIC1_SHIFT;
Packit 577717
		_solaris_vector.cmp_info.hardware_intr = 1;
Packit 577717
		_solaris_vector.cmp_info.hardware_intr_sig = SIGEMT;
Packit 577717
	} else
Packit 577717
		return PAPI_ECMP;
Packit 577717
Packit 577717
	/* Path and args */
Packit 577717
Packit 577717
	pid = getpid(  );
Packit 577717
	if ( pid == -1 )
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
Packit 577717
	/* Turn on microstate accounting for this process and any LWPs. */
Packit 577717
Packit 577717
	sprintf( maxargs, "/proc/%d/ctl", ( int ) pid );
Packit 577717
	if ( ( fd = open( maxargs, O_WRONLY ) ) == -1 )
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	{
Packit 577717
		int retval;
Packit 577717
		struct
Packit 577717
		{
Packit 577717
			long cmd;
Packit 577717
			long flags;
Packit 577717
		} cmd;
Packit 577717
		cmd.cmd = PCSET;
Packit 577717
		cmd.flags = PR_MSACCT | PR_MSFORK;
Packit 577717
		retval = write( fd, &cmd, sizeof ( cmd ) );
Packit 577717
		close( fd );
Packit 577717
		SUBDBG( "Write PCSET returned %d\n", retval );
Packit 577717
		if ( retval != sizeof ( cmd ) )
Packit 577717
			return ( PAPI_ESYS );
Packit 577717
	}
Packit 577717
Packit 577717
	/* Get executable info */
Packit 577717
Packit 577717
	sprintf( maxargs, "/proc/%d/psinfo", ( int ) pid );
Packit 577717
	if ( ( fd = open( maxargs, O_RDONLY ) ) == -1 )
Packit 577717
		return ( PAPI_ESYS );
Packit 577717
	read( fd, &psi, sizeof ( psi ) );
Packit 577717
	close( fd );
Packit 577717
Packit 577717
	/* Cut off any arguments to exe */
Packit 577717
	{
Packit 577717
		char *tmp;
Packit 577717
		tmp = strchr( psi.pr_psargs, ' ' );
Packit 577717
		if ( tmp != NULL )
Packit 577717
			*tmp = '\0';
Packit 577717
	}
Packit 577717
Packit 577717
	if ( realpath( psi.pr_psargs, pname ) )
Packit 577717
		strncpy( _papi_hwi_system_info.exe_info.fullname, pname,
Packit 577717
				 PAPI_HUGE_STR_LEN );
Packit 577717
	else
Packit 577717
		strncpy( _papi_hwi_system_info.exe_info.fullname, psi.pr_psargs,
Packit 577717
				 PAPI_HUGE_STR_LEN );
Packit 577717
Packit 577717
	/* please don't use pr_fname here, because it can only store less that 
Packit 577717
	   16 characters */
Packit 577717
	strcpy( _papi_hwi_system_info.exe_info.address_info.name,
Packit 577717
			basename( _papi_hwi_system_info.exe_info.fullname ) );
Packit 577717
Packit 577717
	SUBDBG( "Full Executable is %s\n",
Packit 577717
			_papi_hwi_system_info.exe_info.fullname );
Packit 577717
Packit 577717
	/* Executable regions, reading /proc/pid/maps file */
Packit 577717
	retval = _ultra_hwd_update_shlib_info( &_papi_hwi_system_info );
Packit 577717
Packit 577717
	/* Hardware info */
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.ncpu = sysconf( _SC_NPROCESSORS_ONLN );
Packit 577717
	_papi_hwi_system_info.hw_info.nnodes = 1;
Packit 577717
	_papi_hwi_system_info.hw_info.totalcpus = sysconf( _SC_NPROCESSORS_CONF );
Packit 577717
Packit 577717
	retval = scan_prtconf( cpuname, PAPI_MAX_STR_LEN, &hz, &version );
Packit 577717
	if ( retval == -1 )
Packit 577717
		return PAPI_ECMP;
Packit 577717
Packit 577717
	strcpy( _papi_hwi_system_info.hw_info.model_string,
Packit 577717
			cpc_getcciname( cpuver ) );
Packit 577717
	_papi_hwi_system_info.hw_info.model = cpuver;
Packit 577717
	strcpy( _papi_hwi_system_info.hw_info.vendor_string, "SUN" );
Packit 577717
	_papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_SUN;
Packit 577717
	_papi_hwi_system_info.hw_info.revision = version;
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.mhz = ( ( float ) hz / 1.0e6 );
Packit 577717
	SUBDBG( "hw_info.mhz = %f\n", _papi_hwi_system_info.hw_info.mhz );
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.cpu_max_mhz = _papi_hwi_system_info.hw_info.mhz;
Packit 577717
	_papi_hwi_system_info.hw_info.cpu_min_mhz = _papi_hwi_system_info.hw_info.mhz;
Packit 577717
Packit 577717
Packit 577717
	/* Number of PMCs */
Packit 577717
Packit 577717
	retval = cpc_getnpic( cpuver );
Packit 577717
	if ( retval < 0 )
Packit 577717
		return PAPI_ECMP;
Packit 577717
Packit 577717
	_solaris_vector.cmp_info.num_cntrs = retval;
Packit 577717
	_solaris_vector.cmp_info.fast_real_timer = 1;
Packit 577717
	_solaris_vector.cmp_info.fast_virtual_timer = 1;
Packit 577717
	_solaris_vector.cmp_info.default_domain = PAPI_DOM_USER;
Packit 577717
	_solaris_vector.cmp_info.available_domains =
Packit 577717
		PAPI_DOM_USER | PAPI_DOM_KERNEL;
Packit 577717
Packit 577717
	/* Setup presets */
Packit 577717
Packit 577717
	retval = _papi_hwi_setup_all_presets( preset_search_map, NULL );
Packit 577717
	if ( retval )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
long long
Packit 577717
_solaris_get_real_usec( void )
Packit 577717
{
Packit 577717
	return ( ( long long ) gethrtime(  ) / ( long long ) 1000 );
Packit 577717
}
Packit 577717
Packit 577717
long long
Packit 577717
_solaris_get_real_cycles( void )
Packit 577717
{
Packit 577717
	return ( _ultra_hwd_get_real_usec(  ) *
Packit 577717
			 ( long long ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
Packit 577717
}
Packit 577717
Packit 577717
long long
Packit 577717
_solaris_get_virt_usec( void )
Packit 577717
{
Packit 577717
	return ( ( long long ) gethrvtime(  ) / ( long long ) 1000 );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
Packit 577717