Ejemplo n.º 1
0
/**
 * adds a Lustre fs to the fs list and creates the counters for it
 * @param name fs name
 * @param procpath_general path to the 'stats' file in /proc/fs/lustre/... for this fs
 * @param procpath_readahead path to the 'readahead' file in /proc/fs/lustre/... for this fs
 */
static int
addLustreFS( const char *name,
	     const char *procpath_general, 
	     const char *procpath_readahead )
{
	lustre_fs *fs, *last;
	char counter_name[512];
	FILE *fff;

	SUBDBG("Adding lustre fs\n");

	fs = malloc( sizeof ( lustre_fs ) );
	if ( fs == NULL ) {
	   SUBDBG("can not allocate memory for new Lustre FS description\n" );
	   return PAPI_ENOMEM;
	}

	fs->proc_file=strdup(procpath_general);
	fff = fopen( procpath_general, "r" );
	if ( fff == NULL ) {
	  SUBDBG("can not open '%s'\n", procpath_general );
	  free(fs);
	  return PAPI_ESYS;
	}
	fclose(fff);

	fs->proc_file_readahead = strdup(procpath_readahead);
	fff = fopen( procpath_readahead, "r" );
	if ( fff == NULL ) {
	  SUBDBG("can not open '%s'\n", procpath_readahead );
	  free(fs);
	  return PAPI_ESYS;
	}
	fclose(fff);

	sprintf( counter_name, "%s_llread", name );
	if (NULL == (fs->read_cntr = addCounter( counter_name, 
				    "bytes read on this lustre client", 
				    "bytes" ))) {
			free(fs);
			return PAPI_ENOMEM;
	}

	sprintf( counter_name, "%s_llwrite", name );
	if ( NULL == (fs->write_cntr = addCounter( counter_name, 
				     "bytes written on this lustre client",
				     "bytes" ))) {
			free(fs->read_cntr);
			free(fs);
			return PAPI_ENOMEM;
	}

	sprintf( counter_name, "%s_wrong_readahead", name );
	if ( NULL == (fs->readahead_cntr = addCounter( counter_name, 
					 "bytes read but discarded due to readahead",
					 "bytes" ))) {
			free(fs->read_cntr);
			free(fs->write_cntr);
			free(fs);
			return PAPI_ENOMEM;
	}

	fs->next = NULL;

	/* Insert into the linked list */
	/* Does this need locking? */
	if ( root_lustre_fs == NULL ) {
		root_lustre_fs = fs;
	} else {
		last = root_lustre_fs;

		while ( last->next != NULL )
			last = last->next;

		last->next = fs;
	}
	return PAPI_OK;
}
Ejemplo n.º 2
0
int
_ultra_hwd_update_shlib_info( papi_mdi_t *mdi )
{
	/*??? system call takes very long */

	char cmd_line[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], fname[L_tmpnam];
	char line[256];
	char address[16], size[10], flags[64], objname[256];
	PAPI_address_map_t *tmp = NULL;

	FILE *f = NULL;
	int t_index = 0, i;
	struct map_record
	{
		long address;
		int size;
		int flags;
		char objname[256];
		struct map_record *next;
	} *tmpr, *head, *curr;

	tmpnam( fname );
	SUBDBG( "Temporary name %s\n", fname );

	sprintf( cmd_line, "/bin/pmap %d > %s", ( int ) getpid(  ), fname );
	if ( system( cmd_line ) != 0 ) {
		PAPIERROR( "Could not run %s to get shared library address map",
				   cmd_line );
		return ( PAPI_OK );
	}

	f = fopen( fname, "r" );
	if ( f == NULL ) {
		PAPIERROR( "fopen(%s) returned < 0", fname );
		remove( fname );
		return ( PAPI_OK );
	}

	/* ignore the first line */
	fgets( line, 256, f );
	head = curr = NULL;
	while ( fgets( line, 256, f ) != NULL ) {
		/* discard the last line */
		if ( strncmp( line, " total", 6 ) != 0 ) {
			sscanf( line, "%s %s %s %s", address, size, flags, objname );
			if ( objname[0] == '/' ) {
				tmpr =
					( struct map_record * )
					papi_malloc( sizeof ( struct map_record ) );
				if ( tmpr == NULL )
					return ( -1 );
				tmpr->next = NULL;
				if ( curr ) {
					curr->next = tmpr;
					curr = tmpr;
				}
				if ( head == NULL ) {
					curr = head = tmpr;
				}

				SUBDBG( "%s\n", objname );

				if ( ( strstr( flags, "read" ) && strstr( flags, "exec" ) ) ||
					 ( strstr( flags, "r" ) && strstr( flags, "x" ) ) ) {
					if ( !( strstr( flags, "write" ) || strstr( flags, "w" ) ) ) {	/* text segment */
						t_index++;
						tmpr->flags = 1;
					} else {
						tmpr->flags = 0;
					}
					sscanf( address, "%lx", &tmpr->address );
					sscanf( size, "%d", &tmpr->size );
					tmpr->size *= 1024;
					strcpy( tmpr->objname, objname );
				}

			}

		}
	}
	tmp =
		( PAPI_address_map_t * ) papi_calloc( t_index - 1,
											  sizeof ( PAPI_address_map_t ) );

	if ( tmp == NULL ) {
		PAPIERROR( "Error allocating shared library address map" );
		return ( PAPI_ENOMEM );
	}

	t_index = -1;
	tmpr = curr = head;
	i = 0;
	while ( curr != NULL ) {
		if ( strcmp( _papi_hwi_system_info.exe_info.address_info.name,
					 basename( curr->objname ) ) == 0 ) {
			if ( curr->flags ) {
				_papi_hwi_system_info.exe_info.address_info.text_start =
					( caddr_t ) curr->address;
				_papi_hwi_system_info.exe_info.address_info.text_end =
					( caddr_t ) ( curr->address + curr->size );
			} else {
				_papi_hwi_system_info.exe_info.address_info.data_start =
					( caddr_t ) curr->address;
				_papi_hwi_system_info.exe_info.address_info.data_end =
					( caddr_t ) ( curr->address + curr->size );
			}
		} else {
			if ( curr->flags ) {
				t_index++;
				tmp[t_index].text_start = ( caddr_t ) curr->address;
				tmp[t_index].text_end =
					( caddr_t ) ( curr->address + curr->size );
				strncpy( tmp[t_index].name, curr->objname,
						 PAPI_HUGE_STR_LEN - 1 );
				tmp[t_index].name[PAPI_HUGE_STR_LEN - 1] = '\0';
			} else {
				if ( t_index < 0 )
					continue;
				tmp[t_index].data_start = ( caddr_t ) curr->address;
				tmp[t_index].data_end =
					( caddr_t ) ( curr->address + curr->size );
			}
		}
		tmpr = curr->next;
		/* free the temporary allocated memory */
		papi_free( curr );
		curr = tmpr;
	}						 /* end of while */

	remove( fname );
	fclose( f );
	if ( _papi_hwi_system_info.shlib_info.map )
		papi_free( _papi_hwi_system_info.shlib_info.map );
	_papi_hwi_system_info.shlib_info.map = tmp;
	_papi_hwi_system_info.shlib_info.count = t_index + 1;

	return ( PAPI_OK );

}
Ejemplo n.º 3
0
/* Initialize hardware counters, setup the function vector table
 * and get hardware information, this routine is called when the 
 * PAPI process is initialized (IE PAPI_library_init)
 *
 * NOTE: only called by main thread (not by every thread) !!!
 *
 * Starting in CUDA 4.0, multiple CPU threads can access the same CUDA context.
 * This is a much easier programming model then pre-4.0 as threads - using the 
 * same context - can share memory, data, etc. 
 * It's possible to create a different context for each thread, but then we are
 * likely running into a limitation that only one context can be profiled at a time.
 * ==> and we don't want this. That's why CUDA context creation is done in 
 * CUDA_init_component() (called only by main thread) rather than CUDA_init() 
 * or CUDA_init_control_state() (both called by each thread).
 */
int
CUDA_init_component( int cidx )
{
	SUBDBG ("Entry: cidx: %d\n", cidx);
	CUresult cuErr = CUDA_SUCCESS;

	/* link in all the cuda libraries and resolve the symbols we need to use */
	if (linkCudaLibraries() != PAPI_OK) {
		SUBDBG ("Dynamic link of CUDA libraries failed, component will be disabled.\n");
		SUBDBG ("See disable reason in papi_component_avail output for more details.\n");
		return (PAPI_ENOSUPP);
	}

	/* Create dynamic event table */
	NUM_EVENTS = detectDevice(  );
	if (NUM_EVENTS < 0) {
		strncpy(_cuda_vector.cmp_info.disabled_reason, "Call to detectDevice failed.",PAPI_MAX_STR_LEN);
		return (PAPI_ENOSUPP);
	}
	/* TODO: works only for one device right now;
	 need to find out if user can use 2 or more devices at same time */

	/* want create a CUDA context for either the default device or
	 the device specified with cudaSetDevice() in user code */
	if ( CUDA_SUCCESS != (*cudaGetDevicePtr)( &currentDeviceID ) ) {
		strncpy(_cuda_vector.cmp_info.disabled_reason, "No NVIDIA GPU's found.",PAPI_MAX_STR_LEN);
		return ( PAPI_ENOSUPP );
	}
	
	if ( getenv( "PAPI_VERBOSE" ) ) {
		printf( "DEVICE USED: %s (%d)\n", device[currentDeviceID].name,
			   currentDeviceID );
	}
	
	/* get the CUDA context from the calling CPU thread */
	cuErr = (*cuCtxGetCurrentPtr)( &cuCtx );

	/* if no CUDA context is bound to the calling CPU thread yet, create one */
	if ( cuErr != CUDA_SUCCESS || cuCtx == NULL ) {
		cuErr = (*cuCtxCreatePtr)( &cuCtx, 0, device[currentDeviceID].dev );
		CHECK_CU_ERROR( cuErr, "cuCtxCreate" );
	}

	/* cuCtxGetCurrent() can return a non-null context that is not valid 
	   because the context has not yet been initialized.
	   Here is a workaround: 
	   cudaFree(NULL) forces the context to be initialized
	   if cudaFree(NULL) returns success then we are able to use the context in subsequent calls
	   if cudaFree(NULL) returns an error (or subsequent cupti* calls) then the context is not usable,
	   and will never be useable */
	if ( CUDA_SUCCESS != (*cudaFreePtr)( NULL ) ) {
		strncpy(_cuda_vector.cmp_info.disabled_reason, "Problem initializing CUDA context.",PAPI_MAX_STR_LEN);
		return ( PAPI_ENOSUPP );
	}

	/* Create dynamic event table */
	cuda_native_table = ( CUDA_native_event_entry_t * )
		malloc( sizeof ( CUDA_native_event_entry_t ) * NUM_EVENTS );
	if ( cuda_native_table == NULL ) {
		perror( "malloc(): Failed to allocate memory to events table" );
		strncpy(_cuda_vector.cmp_info.disabled_reason, "Failed to allocate memory to events table.",PAPI_MAX_STR_LEN);
		return ( PAPI_ENOSUPP );
	}

	if ( NUM_EVENTS != createNativeEvents(  ) ) {
		strncpy(_cuda_vector.cmp_info.disabled_reason, "Error creating CUDA event list.",PAPI_MAX_STR_LEN);
		return ( PAPI_ENOSUPP );
	}
	
	/* Export the component id */
	_cuda_vector.cmp_info.CmpIdx = cidx;

	return ( PAPI_OK );
}
Ejemplo n.º 4
0
/*
 * find all network interfaces listed in /proc/net/dev
 */
static int
generateNetEventList( void )
{
    FILE *fin;
    char line[NET_PROC_MAX_LINE];
    char *retval, *ifname;
    int count = 0;
    struct temp_event *temp;
    struct temp_event *last = NULL;
    int i, j;

    fin = fopen(NET_PROC_FILE, "r");
    if (fin == NULL) {
        SUBDBG("Can't find %s, are you sure the /proc file-system is mounted?\n",
           NET_PROC_FILE);
        return 0;
    }

    /* skip the 2 header lines */
    for (i=0; i<2; i++) {
        retval = fgets (line, NET_PROC_MAX_LINE, fin);
        if (retval == NULL) {
        	fclose(fin);
            SUBDBG("Not enough lines in %s\n", NET_PROC_FILE);
            return 0;
        }
    }

    while ((fgets (line, NET_PROC_MAX_LINE, fin)) == line) {

        /* split the interface name from the 16 counters */
        retval = strstr(line, ":");
        if (retval == NULL) {
            SUBDBG("Wrong line format <%s>\n", line);
            continue;
        }

        *retval = '\0';
        ifname = line;
        while (isspace(*ifname)) { ifname++; }

        for (j=0; j<NET_INTERFACE_COUNTERS; j++) {

            /* keep the interface name around */
            temp = (struct temp_event *)papi_malloc(sizeof(struct temp_event));
            if (!temp) {
                PAPIERROR("out of memory!");
                fclose(fin);
                return PAPI_ENOMEM;
            }
            temp->next = NULL;

            if (root == NULL) {
                root = temp;
            } else if (last) {
                last->next = temp;
            } else {
                free(temp);
                fclose(fin);
                PAPIERROR("This shouldn't be possible\n");
                return PAPI_ESBSTR;
            }
            last = temp;

            snprintf(temp->name, PAPI_MAX_STR_LEN, "%s.%s",
                    ifname, _net_counter_info[j].name);
            snprintf(temp->description, PAPI_MAX_STR_LEN, "%s %s",
                    ifname, _net_counter_info[j].description);

            count++;
        }
    }

    fclose(fin);

    return count;
}
Ejemplo n.º 5
0
int
_perfctr_init_component( int cidx )
{
	int retval;
	struct perfctr_info info;
	char abiv[PAPI_MIN_STR_LEN];

#if defined(PERFCTR26)
	int fd;
#else
	struct vperfctr *dev;
#endif

#if defined(PERFCTR26)
	/* Get info from the kernel */
	/* Use lower level calls per Mikael to get the perfctr info
	   without actually creating a new kernel-side state.
	   Also, close the fd immediately after retrieving the info.
	   This is much lighter weight and doesn't reserve the counter
	   resources. Also compatible with perfctr 2.6.14.
	 */
	fd = _vperfctr_open( 0 );
	if ( fd < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VOPEN_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}
	retval = perfctr_info( fd, &info );
	close( fd );
	if ( retval < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VINFO_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}

	/* copy tsc multiplier to local variable        */
	/* this field appears in perfctr 2.6 and higher */
	tb_scale_factor = ( long long ) info.tsc_to_cpu_mult;
#else
	/* Opened once for all threads. */
	if ( ( dev = vperfctr_open(  ) ) == NULL ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VOPEN_ERROR,PAPI_MAX_STR_LEN);
	   return PAPI_ESYS;
	}
	SUBDBG( "_perfctr_init_component vperfctr_open = %p\n", dev );

	/* Get info from the kernel */
	retval = vperfctr_info( dev, &info );
	if ( retval < 0 ) {
	   strncpy(_perfctr_vector.cmp_info.disabled_reason,
		  VINFO_ERROR,PAPI_MAX_STR_LEN);
		return ( PAPI_ESYS );
	}
	vperfctr_close( dev );
#endif

	/* Fill in what we can of the papi_system_info. */
	retval = _papi_os_vector.get_system_info( &_papi_hwi_system_info );
	if ( retval != PAPI_OK )
		return ( retval );

	/* Setup memory info */
	retval = _papi_os_vector.get_memory_info( &_papi_hwi_system_info.hw_info,
						   ( int ) info.cpu_type );
	if ( retval )
		return ( retval );

	strcpy( _perfctr_vector.cmp_info.name,"perfctr.c" );
	strcpy( _perfctr_vector.cmp_info.version, "$Revision$" );
	sprintf( abiv, "0x%08X", info.abi_version );
	strcpy( _perfctr_vector.cmp_info.support_version, abiv );
	strcpy( _perfctr_vector.cmp_info.kernel_version, info.driver_version );
	_perfctr_vector.cmp_info.CmpIdx = cidx;
	_perfctr_vector.cmp_info.num_cntrs = ( int ) PERFCTR_CPU_NRCTRS( &info );
        _perfctr_vector.cmp_info.num_mpx_cntrs=_perfctr_vector.cmp_info.num_cntrs;
	if ( info.cpu_features & PERFCTR_FEATURE_RDPMC )
		_perfctr_vector.cmp_info.fast_counter_read = 1;
	else
		_perfctr_vector.cmp_info.fast_counter_read = 0;
	_perfctr_vector.cmp_info.fast_real_timer = 1;
	_perfctr_vector.cmp_info.fast_virtual_timer = 1;
	_perfctr_vector.cmp_info.attach = 1;
	_perfctr_vector.cmp_info.attach_must_ptrace = 1;
	_perfctr_vector.cmp_info.default_domain = PAPI_DOM_USER;
#if !defined(PPC64)
	/* AMD and Intel ia386 processors all support unit mask bits */
	_perfctr_vector.cmp_info.cntr_umasks = 1;
#endif
#if defined(PPC64)
	_perfctr_vector.cmp_info.available_domains =
		PAPI_DOM_USER | PAPI_DOM_KERNEL | PAPI_DOM_SUPERVISOR;
#else
	_perfctr_vector.cmp_info.available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL;
#endif
	_perfctr_vector.cmp_info.default_granularity = PAPI_GRN_THR;
	_perfctr_vector.cmp_info.available_granularities = PAPI_GRN_THR;
	if ( info.cpu_features & PERFCTR_FEATURE_PCINT )
		_perfctr_vector.cmp_info.hardware_intr = 1;
	else
		_perfctr_vector.cmp_info.hardware_intr = 0;
	SUBDBG( "Hardware/OS %s support counter generated interrupts\n",
			_perfctr_vector.cmp_info.hardware_intr ? "does" : "does not" );

	strcpy( _papi_hwi_system_info.hw_info.model_string,
			PERFCTR_CPU_NAME( &info ) );
	_papi_hwi_system_info.hw_info.model = ( int ) info.cpu_type;
#if defined(PPC64)
	_papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_IBM;
	if ( strlen( _papi_hwi_system_info.hw_info.vendor_string ) == 0 )
		strcpy( _papi_hwi_system_info.hw_info.vendor_string, "IBM" );
#else
	_papi_hwi_system_info.hw_info.vendor =
		xlate_cpu_type_to_vendor( info.cpu_type );
#endif

	/* Setup presets last. Some platforms depend on earlier info */
#if !defined(PPC64)
//     retval = setup_p3_vector_table(vtable);
		if ( !retval )
			retval = setup_x86_presets( ( int ) info.cpu_type );
#else
	/* Setup native and preset events */
//  retval = ppc64_setup_vector_table(vtable);
	if ( !retval )
		retval = perfctr_ppc64_setup_native_table(  );
	if ( !retval )
		retval = setup_ppc64_presets( info.cpu_type );
#endif
	if ( retval )
		return ( retval );

	return ( PAPI_OK );
}
Ejemplo n.º 6
0
int
_niagara2_get_system_info( papi_mdi_t *mdi )
{
	// Used for evaluating return values
	int retval = 0;
	// Check for process settings
	pstatus_t *proc_status;
	psinfo_t *proc_info;
	// Used for string truncating
	char *c_ptr;
	// For retrieving the executable full name
	char exec_name[PAPI_HUGE_STR_LEN];
	// For retrieving processor information
	__sol_processor_information_t cpus;

#ifdef DEBUG
	SUBDBG( "ENTERING FUNCTION >>%s<< at %s:%d\n", __func__, __FILE__,
			__LINE__ );
#endif

	/* Get and set pid */
	pid = getpid(  );

	/* Check for microstate accounting */
	proc_status = __sol_get_proc_status( pid );

	if ( proc_status->pr_flags & PR_MSACCT == 0 ||
		 proc_status->pr_flags & PR_MSFORK == 0 ) {
		/* Solaris 10 should have microstate accounting always activated */
		return PAPI_ECMP;
	}

	/* Fill _papi_hwi_system_info.exe_info.fullname */
	proc_info = __sol_get_proc_info( pid );

	// If there are arguments, trim the string to the executable name.
	if ( proc_info->pr_argc > 1 ) {
		c_ptr = strchr( proc_info->pr_psargs, ' ' );
		if ( c_ptr != NULL )
			c_ptr = '\0';
	}

	/* If the path can be qualified, use the full path, otherwise the trimmed
	   name. */
	if ( realpath( proc_info->pr_psargs, exec_name ) != NULL ) {
		strncpy( _papi_hwi_system_info.exe_info.fullname, exec_name,
				 PAPI_HUGE_STR_LEN );
	} else {
		strncpy( _papi_hwi_system_info.exe_info.fullname, proc_info->pr_psargs,
				 PAPI_HUGE_STR_LEN );
	}

	/* Fill _papi_hwi_system_info.exe_info.address_info */
	// Taken from the old component
	strncpy( _papi_hwi_system_info.exe_info.address_info.name,
			 basename( _papi_hwi_system_info.exe_info.fullname ),
			 PAPI_HUGE_STR_LEN );
	__CHECK_ERR_PAPI( _niagara2_update_shlib_info( &_papi_hwi_system_info ) );

	/* Fill _papi_hwi_system_info.hw_info */

	// Taken from the old component
	_papi_hwi_system_info.hw_info.ncpu = sysconf( _SC_NPROCESSORS_ONLN );
	_papi_hwi_system_info.hw_info.nnodes = 1;
	_papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_SUN;
	strcpy( _papi_hwi_system_info.hw_info.vendor_string, "SUN" );
	_papi_hwi_system_info.hw_info.totalcpus = sysconf( _SC_NPROCESSORS_CONF );
	_papi_hwi_system_info.hw_info.model = 1;
	strcpy( _papi_hwi_system_info.hw_info.model_string, cpc_cciname( cpc ) );

	/* The field sparc-version is no longer in prtconf -pv */
	_papi_hwi_system_info.hw_info.revision = 1;

	/* Clock speed */
	_papi_hwi_system_info.hw_info.mhz = ( float ) __sol_get_processor_clock(  );
	_papi_hwi_system_info.hw_info.clock_mhz = __sol_get_processor_clock(  );
	_papi_hwi_system_info.hw_info.cpu_max_mhz = __sol_get_processor_clock(  );
	_papi_hwi_system_info.hw_info.cpu_min_mhz = __sol_get_processor_clock(  );

	/* Fill _niagara2_vector.cmp_info.mem_hierarchy */

	_niagara2_get_memory_info( &_papi_hwi_system_info.hw_info, 0 );

	/* Fill _papi_hwi_system_info.sub_info */
	strcpy( _niagara2_vector.cmp_info.name, "SunNiagara2" );
	strcpy( _niagara2_vector.cmp_info.version, "ALPHA" );
	strcpy( _niagara2_vector.cmp_info.support_version, "libcpc2" );
	strcpy( _niagara2_vector.cmp_info.kernel_version, "libcpc2" );

	/* libcpc2 uses SIGEMT using real hardware signals, no sw emu */

#ifdef DEBUG
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
			__LINE__ );
#endif

	return PAPI_OK;
}
Ejemplo n.º 7
0
static int
load_preset_table( char *pmu_str, int pmu_type,
				   pfm_preset_search_entry_t * here )
{

	char pmu_name[PAPI_MIN_STR_LEN];
	char line[LINE_MAX];
	char name[PATH_MAX] = "builtin papi_events_table";
	char *tmp_papi_events_table = NULL;
	char *tmpn;
	FILE *table;
	int line_no = 1, derived = 0, insert = 0, preset = 0;
	int get_presets = 0;			   /* only get PRESETS after CPU is identified */
	int found_presets = 0;			   /* only terminate search after PRESETS are found */
	/* this allows support for synonyms for CPU names */

  SUBDBG("ENTER\n");

#ifdef SHOW_LOADS
	SUBDBG( "%p\n", here );
#endif

	/* copy the pmu identifier, stripping commas if found */
	tmpn = pmu_name;
	while ( *pmu_str ) {
		if ( *pmu_str != ',' )
			*tmpn++ = *pmu_str;
		pmu_str++;
	}
	*tmpn = '\0';

        /* FIXME -- make sure PAPI_TOT_CYC and PAPI_TOT_INS are #1/#2 */

	/* try the environment variable first */
	if ( ( tmpn = getenv( "PAPI_PERFMON_EVENT_FILE" ) ) &&
		 ( strlen( tmpn ) != 0 ) ) {
		sprintf( name, "%s", tmpn );
		table = fopen( name, "r" );
	}
	/* if no valid environment variable, look for built-in table */
	else if ( papi_events_table ) {
		tmp_papi_events_table = papi_events_table;
		table = NULL;
	}
	/* if no env var and no built-in, search for default file */
	else {
#ifdef PAPI_DATADIR
		sprintf( name, "%s/%s", PAPI_DATADIR, PAPI_EVENT_FILE );
#else
		sprintf( name, "%s", PAPI_EVENT_FILE );
#endif
		table = open_event_table( name );
	}
	/* if no valid file or built-in table, bail */
	if ( table == NULL && tmp_papi_events_table == NULL ) {
		PAPIERROR
			( "fopen(%s): %s, please set the PAPI_PERFMON_EVENT_FILE env. variable",
			  name, strerror( errno ) );
		return ( PAPI_ESYS );
	}

	/* at this point either a valid file pointer or built-in table pointer */
	while ( get_event_line( line, table, &tmp_papi_events_table ) ) {
		char *t;
		int i;
		t = trim_string( strtok( line, "," ) );
		if ( ( t == NULL ) || ( strlen( t ) == 0 ) )
			continue;
		if ( t[0] == '#' ) {
/*	  SUBDBG("Comment found on line %d\n",line_no); */
			goto nextline;
		} else if ( strcasecmp( t, "CPU" ) == 0 ) {
#ifdef SHOW_LOADS
			SUBDBG( "CPU token found on line %d\n", line_no );
#endif
			if ( get_presets != 0 && found_presets != 0 ) {
#ifdef SHOW_LOADS
				SUBDBG( "Ending preset scanning at line %d of %s.\n", line_no,
						name );
#endif
				get_presets=0; found_presets=0;
				/* goto done; */
			}
			t = trim_string( strtok( NULL, "," ) );
			if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
				PAPIERROR
					( "Expected name after CPU token at line %d of %s -- ignoring",
					  line_no, name );
				goto nextline;
			}
#ifdef SHOW_LOADS
			SUBDBG( "Examining CPU (%s) vs. (%s)\n", t, pmu_name );
#endif
			if ( strcasecmp( t, pmu_name ) == 0 ) {
				int type;

#ifdef SHOW_LOADS
				SUBDBG( "Found CPU %s at line %d of %s.\n", t, line_no, name );
#endif
				t = trim_string( strtok( NULL, "," ) );
				if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
#ifdef SHOW_LOADS
					SUBDBG
						( "No additional qualifier found, matching on string.\n" );
#endif
					get_presets = 1;
				} else if ( ( sscanf( t, "%d", &type ) == 1 ) &&
							( type == pmu_type ) ) {
#ifdef SHOW_LOADS
					SUBDBG( "Found CPU %s type %d at line %d of %s.\n",
							pmu_name, type, line_no, name );
#endif
					get_presets = 1;
				} else {
#ifdef SHOW_LOADS
					SUBDBG( "Additional qualifier match failed %d vs %d.\n",
							pmu_type, type );
#endif
				}
			}
		} else if ( strcasecmp( t, "PRESET" ) == 0 ) {
#ifdef SHOW_LOADS
//			SUBDBG( "PRESET token found on line %d\n", line_no );
#endif
			if ( get_presets == 0 )
				goto nextline;
			found_presets = 1;
			t = trim_string( strtok( NULL, "," ) );
			if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
				PAPIERROR
					( "Expected name after PRESET token at line %d of %s -- ignoring",
					  line_no, name );
				goto nextline;
			}
#ifdef SHOW_LOADS
			SUBDBG( "Examining preset %s\n", t );
#endif
			if ( find_preset_code( t, &preset ) != PAPI_OK ) {
				PAPIERROR
					( "Invalid preset name %s after PRESET token at line %d of %s -- ignoring",
					  t, line_no, name );
				goto nextline;
			}

			SUBDBG( "Found 0x%08x for %s\n", preset, t );

			t = trim_string( strtok( NULL, "," ) );
			if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
				PAPIERROR
					( "Expected derived type after PRESET token at line %d of %s -- ignoring",
					  line_no, name );
				goto nextline;
			}
#ifdef SHOW_LOADS
			SUBDBG( "Examining derived %s\n", t );
#endif
			if ( _papi_hwi_derived_type( t, &derived ) != PAPI_OK ) {
				PAPIERROR
					( "Invalid derived name %s after PRESET token at line %d of %s -- ignoring",
					  t, line_no, name );
				goto nextline;
			}

			SUBDBG( "Found %d for %s\n", derived, t );
			SUBDBG( "Adding 0x%x,%d to preset search table.\n", preset,
					derived );

			here[insert].preset = preset;
			here[insert].derived = derived;

			/* Derived support starts here */
			/* Special handling for postfix */
			if ( derived == DERIVED_POSTFIX ) {
				t = trim_string( strtok( NULL, "," ) );
				if ( ( t == NULL ) || ( strlen( t ) == 0 ) ) {
					PAPIERROR
						( "Expected Operation string after derived type DERIVED_POSTFIX at line %d of %s -- ignoring",
						  line_no, name );
					goto nextline;
				}
#ifdef SHOW_LOADS
				SUBDBG( "Saving PostFix operations %s\n", t );
#endif
				here[insert].operation = strdup( t );
			}
			/* All derived terms collected here */
			i = 0;
			do {
				t = trim_string( strtok( NULL, "," ) );
				if ( ( t == NULL ) || ( strlen( t ) == 0 ) )
					break;
				if ( strcasecmp( t, "NOTE" ) == 0 )
					break;
				here[insert].findme[i] = strdup( t );
#ifdef SHOW_LOADS
				SUBDBG( "Adding term (%d) %s to preset event 0x%x.\n", i, t,
						preset );
#endif
			} while ( ++i < PAPI_MAX_COUNTER_TERMS );
			/* End of derived support */

			if ( i == 0 ) {
				PAPIERROR
					( "Expected PFM event after DERIVED token at line %d of %s -- ignoring",
					  line_no, name );
				goto nextline;
			}
			if ( i == PAPI_MAX_COUNTER_TERMS )
				t = trim_string( strtok( NULL, "," ) );

			/* Handle optional NOTEs */
			if ( t && ( strcasecmp( t, "NOTE" ) == 0 ) ) {
#ifdef SHOW_LOADS
				SUBDBG( "%s found on line %d\n", t, line_no );
#endif
				t = trim_note( strtok( NULL, "" ) );	/* read the rest of the line */
				if ( ( t == NULL ) || ( strlen( t ) == 0 ) )
					PAPIERROR( "Expected Note string at line %d of %s\n",
							   line_no, name );
				else {
					here[insert].note = strdup( t );
#ifdef SHOW_LOADS
					SUBDBG( "NOTE: --%s-- found on line %d\n", t, line_no );
#endif
				}
			}

			insert++;
			SUBDBG( "# events inserted: --%d-- \n", insert );
		} else {
			PAPIERROR( "Unrecognized token %s at line %d of %s -- ignoring", t,
					   line_no, name );
			goto nextline;
		}
	  nextline:
		line_no++;
	}
/*  done: */
	if ( table )
		fclose( table );

	return PAPI_OK;
}
Ejemplo n.º 8
0
void
_vectors_error(  )
{
	SUBDBG( "function is not implemented in the component!\n" );
	exit( PAPI_ESBSTR );
}
Ejemplo n.º 9
0
/*
 * Set Overflow
 *
 * This is commented out in BG/L/P - need to explore and complete...
 * However, with true 64-bit counters in BG/Q and all counters for PAPI
 * always starting from a true zero (we don't allow write...), the possibility
 * for overflow is remote at best...
 */
int
L2UNIT_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
{
#ifdef DEBUG_BGQ
	printf("BEGIN L2UNIT_set_overflow\n");
#endif
	L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ESI->ctl_state;
	int retval;
	int evt_idx;
	
	/*
	 * In case an BGPM eventGroup HAS BEEN applied or attached before
	 * overflow is set, delete the eventGroup and create an new empty one,
	 * and rebuild as it was prior to deletion
	 */
#ifdef DEBUG_BGQ
	printf( "L2UNIT_set_overflow: bgpm_eventset_applied = %d, threshold = %d\n",
		   this_state->bgpm_eventset_applied, threshold );
#endif	
	if ( 1 == this_state->bgpm_eventset_applied && 0 != threshold ) {
		_common_deleteRecreate( &this_state->EventGroup );
		_common_rebuildEventgroup( this_state->count,
								  this_state->EventGroup_local,
								  &this_state->EventGroup );
		
		/* set BGPM eventGroup flag back to NOT applied yet (0) 
		 * because the eventGroup has been recreated from scratch */
		this_state->bgpm_eventset_applied = 0;
	}
		
	evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
	SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
		   evt_idx, EventIndex, threshold );
#ifdef DEBUG_BGQ
	printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
		   evt_idx, EventIndex, threshold );
#endif
	/* If this counter isn't set to overflow, it's an error */
	if ( threshold == 0 ) {
		/* Remove the signal handler */
		retval = _papi_hwi_stop_signal( _L2unit_vector.cmp_info.hardware_intr_sig );
		if ( retval != PAPI_OK )
			return ( retval );
	}
	else {
		this_state->overflow = 1;
        this_state->overflow_count++;
		this_state->overflow_list[this_state->overflow_count-1].threshold = threshold;
		this_state->overflow_list[this_state->overflow_count-1].EventIndex = evt_idx;
		
#ifdef DEBUG_BGQ
		printf( "L2UNIT_set_overflow: Enable the signal handler\n" );
#endif
		/* Enable the signal handler */
		retval = _papi_hwi_start_signal( _L2unit_vector.cmp_info.hardware_intr_sig, 
										NEED_CONTEXT, 
										_L2unit_vector.cmp_info.CmpIdx );
		if ( retval != PAPI_OK )
			return ( retval );

        _common_set_overflow_BGPM( this_state->EventGroup,
                                  this_state->overflow_list[this_state->overflow_count-1].EventIndex,
                                  this_state->overflow_list[this_state->overflow_count-1].threshold,
                                  user_signal_handler_L2UNIT );
	}
	
	return ( PAPI_OK );
}
Ejemplo n.º 10
0
int
_linux_get_system_info( papi_mdi_t *mdi ) {

	int retval;

	char maxargs[PAPI_HUGE_STR_LEN];
	pid_t pid;

	/* 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 );
	if ( retval )
		return retval;

	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 %f Mhz, clock %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.mhz, mdi->hw_info.clock_mhz );

	return PAPI_OK;
}
Ejemplo n.º 11
0
/* Open all events in the control state */
int
open_pe_events(pe_control_t *ctl)
{

    int i, ret = PE_OK;
    long pid = ctl->tid;

    for (i = 0; i < ctl->num_events; i++)
    {

        ctl->events[i].event_opened = 0;

        /* set up the attr structure.  We don't set up all fields here */
        /* as some have already been set up previously.                */

        /* group leader (event 0) is special                */
        if (i == 0)
        {
            ctl->events[i].attr.pinned = 1;
            ctl->events[i].attr.disabled = 1;
            ctl->events[i].group_leader_fd = -1;
        }
        else
        {
            ctl->events[i].attr.pinned = 0;
            ctl->events[i].attr.disabled = 0;
            ctl->events[i].group_leader_fd = ctl->events[0].event_fd;
        }

        /* try to open */
        ctl->events[i].event_fd = sys_perf_event_open(&ctl->events[i].attr, pid,
                                  ctl->cpu, ctl->events[i].group_leader_fd, 0 /* flags */
                                                     );

        if (ctl->events[i].event_fd == -1)
        {
            SUBDBG("sys_perf_event_open returned error on event #%d."
                   "  Error: %s\n", i, strerror(errno));
            if (errno == EPERM)
                ret = PE_EPERM;
            else
                ret = PE_ECNFLCT;
            goto open_pe_cleanup;
        }

        SUBDBG("sys_perf_event_open: tid: %ld, cpu_num: %d,"
               " group_leader/fd: %d, event_fd: %d,"
               " read_format: 0x%"PRIu64"\n", pid, ctl->cpu,
               ctl->events[i].group_leader_fd, ctl->events[i].event_fd,
               ctl->events[i].attr.read_format);

        ctl->events[i].event_opened = 1;
    }

    /* Now that we've successfully opened all of the events, do whatever  */
    /* "tune-up" is needed to attach the mmap'd buffers, signal handlers, */
    /* and so on.                                                         */
    for (i = 0; i < ctl->num_events; i++)
    {

        /* If sampling is enabled, hook up signal handler */
        if (ctl->events[i].attr.sample_period)
        {
            ret = prepare_fd(ctl, i);
            if (ret != PE_OK)
            {
                /* All of the fds are open, so we need to clean up all of them */
                i = ctl->num_events;
                goto open_pe_cleanup;
            }
        }
        else
        {
            /* Make sure this is NULL so close_pe_events works right */
            ctl->events[i].mmap_buf = NULL;
        }
    }

    return PE_OK;

open_pe_cleanup:
    /* We encountered an error, close up the fds we successfully opened.  */
    /* We go backward in an attempt to close group leaders last, although */
    /* That's probably not strictly necessary.                            */
    while (i > 0)
    {
        i--;
        if (ctl->events[i].event_fd >= 0)
        {
            close(ctl->events[i].event_fd);
            ctl->events[i].event_opened = 0;
        }
    }

    return ret;
}
Ejemplo n.º 12
0
int
_papi_libpfm_setup_counters( struct perf_event_attr *attr, 
			   hwd_register_t *ni_bits ) {

  int ret,pe_event;
  (void)ni_bits;

    /*
     * We need an event code that is common across all counters.
     * The implementation is required to know how to translate the supplied
     * code to whichever counter it ends up on.
     */

#if defined(__powerpc__)
    int code;
    ret = pfm_get_event_code_counter( ( ( pfm_register_t * ) ni_bits )->event, 0, &code );
    if ( ret ) {
       /* Unrecognized code, but should never happen */
       return PAPI_EBUG;
    }
    pe_event = code;
    SUBDBG( "Stuffing native event index (code 0x%x, raw code 0x%x) into events array.\n",
				  ( ( pfm_register_t * ) ni_bits )->event, code );
#else

   pfmlib_input_param_t inp;
   pfmlib_output_param_t outp;

   memset( &inp, 0, sizeof ( inp ) );
   memset( &outp, 0, sizeof ( outp ) );
   inp.pfp_event_count = 1;
   inp.pfp_dfl_plm = PAPI_DOM_USER;
   pfm_regmask_set( &inp.pfp_unavail_pmcs, 16 );	// mark fixed counters as unavailable

    inp.pfp_events[0] = *( ( pfm_register_t * ) ni_bits );
    ret = pfm_dispatch_events( &inp, NULL, &outp, NULL );
    if (ret != PFMLIB_SUCCESS) {
       SUBDBG( "Error: pfm_dispatch_events returned: %d\n", ret);
       return PAPI_ESYS;
    }
		   	
       /* Special case p4 */
    if (( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_INTEL ) && 
        ( _papi_hwi_system_info.hw_info.cpuid_family == 15)) {

	pe_event=generate_p4_event( outp.pfp_pmcs[0].reg_value, /* escr */  
		                    outp.pfp_pmcs[1].reg_value, /* cccr */
		                    outp.pfp_pmcs[0].reg_addr); /* escr_addr */
    }
    else {
        pe_event = outp.pfp_pmcs[0].reg_value;   
    }
    SUBDBG( "pe_event: 0x%llx\n", outp.pfp_pmcs[0].reg_value );
#endif

    attr->config=pe_event;

    /* for libpfm3 we currently only handle RAW type */
    attr->type=PERF_TYPE_RAW;

    return PAPI_OK;
}
Ejemplo n.º 13
0
int
_papi_libpfm_init(papi_vector_t *my_vector, int cidx) {

   int retval;
   unsigned int ncnt;
   unsigned int version;
   char pmu_name[PAPI_MIN_STR_LEN];


   /* The following checks the version of the PFM library
      against the version PAPI linked to... */
   SUBDBG( "pfm_initialize()\n" );
   if ( ( retval = pfm_initialize(  ) ) != PFMLIB_SUCCESS ) {
      PAPIERROR( "pfm_initialize(): %s", pfm_strerror( retval ) );
      return PAPI_ESYS;
   }

   /* Get the libpfm3 version */
   SUBDBG( "pfm_get_version(%p)\n", &version );
   if ( pfm_get_version( &version ) != PFMLIB_SUCCESS ) {
      PAPIERROR( "pfm_get_version(%p): %s", version, pfm_strerror( retval ) );
      return PAPI_ESYS;
   }

   /* Set the version */
   sprintf( my_vector->cmp_info.support_version, "%d.%d",
	    PFM_VERSION_MAJOR( version ), PFM_VERSION_MINOR( version ) );

   /* Complain if the compiled-against version doesn't match current version */
   if ( PFM_VERSION_MAJOR( version ) != PFM_VERSION_MAJOR( PFMLIB_VERSION ) ) {
      PAPIERROR( "Version mismatch of libpfm: compiled %x vs. installed %x\n",
				   PFM_VERSION_MAJOR( PFMLIB_VERSION ),
				   PFM_VERSION_MAJOR( version ) );
      return PAPI_ESYS;
   }

   /* Always initialize globals dynamically to handle forks properly. */

   _perfmon2_pfm_pmu_type = -1;

   /* Opened once for all threads. */
   SUBDBG( "pfm_get_pmu_type(%p)\n", &_perfmon2_pfm_pmu_type );
   if ( pfm_get_pmu_type( &_perfmon2_pfm_pmu_type ) != PFMLIB_SUCCESS ) {
      PAPIERROR( "pfm_get_pmu_type(%p): %s", _perfmon2_pfm_pmu_type,
				   pfm_strerror( retval ) );
      return PAPI_ESYS;
   }

   pmu_name[0] = '\0';
   if ( pfm_get_pmu_name( pmu_name, PAPI_MIN_STR_LEN ) != PFMLIB_SUCCESS ) {
      PAPIERROR( "pfm_get_pmu_name(%p,%d): %s", pmu_name, PAPI_MIN_STR_LEN,
				   pfm_strerror( retval ) );
      return PAPI_ESYS;
   }
   SUBDBG( "PMU is a %s, type %d\n", pmu_name, _perfmon2_pfm_pmu_type );

   /* Setup presets */
   retval = _papi_load_preset_table( pmu_name, _perfmon2_pfm_pmu_type, cidx );
   if ( retval )
      return retval;

   /* Fill in cmp_info */

   SUBDBG( "pfm_get_num_events(%p)\n", &ncnt );
   if ( ( retval = pfm_get_num_events( &ncnt ) ) != PFMLIB_SUCCESS ) {
      PAPIERROR( "pfm_get_num_events(%p): %s\n", &ncnt,
				   pfm_strerror( retval ) );
      return PAPI_ESYS;
   }
   SUBDBG( "pfm_get_num_events: %d\n", ncnt );
   my_vector->cmp_info.num_native_events = ncnt;
   num_native_events = ncnt;

   pfm_get_num_counters( ( unsigned int * ) &my_vector->cmp_info.num_cntrs );
   SUBDBG( "pfm_get_num_counters: %d\n", my_vector->cmp_info.num_cntrs );


   if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_INTEL ) {
     /* Pentium4 */
     if ( _papi_hwi_system_info.hw_info.cpuid_family == 15 ) {
       PAPI_NATIVE_EVENT_AND_MASK = 0x000000ff;
       PAPI_NATIVE_UMASK_AND_MASK = 0x0fffff00;
       PAPI_NATIVE_UMASK_SHIFT = 8;
       /* Itanium2 */
     } else if ( _papi_hwi_system_info.hw_info.cpuid_family == 31 ||
		 _papi_hwi_system_info.hw_info.cpuid_family == 32 ) {
       PAPI_NATIVE_EVENT_AND_MASK = 0x00000fff;
       PAPI_NATIVE_UMASK_AND_MASK = 0x0ffff000;
       PAPI_NATIVE_UMASK_SHIFT = 12;
     }
   }


   return PAPI_OK;
}
Ejemplo n.º 14
0
int
_papi_hwd_get_system_info( void )
{
	struct wininfo win_hwinfo;
	HMODULE hModule;
	DWORD len;
	long i = 0;

	/* Path and args */
	_papi_hwi_system_info.pid = getpid(  );

	hModule = GetModuleHandle( NULL );	// current process
	len =
		GetModuleFileName( hModule, _papi_hwi_system_info.exe_info.fullname,
						   PAPI_MAX_STR_LEN );
	if ( len )
		splitpath( _papi_hwi_system_info.exe_info.fullname,
				   _papi_hwi_system_info.exe_info.address_info.name );
	else
		return ( PAPI_ESYS );

	SUBDBG( "Executable is %s\n",
			_papi_hwi_system_info.exe_info.address_info.name );
	SUBDBG( "Full Executable is %s\n",
			_papi_hwi_system_info.exe_info.fullname );
	/* Hardware info */
	if ( !init_hwinfo( &win_hwinfo ) )
		return ( PAPI_ESYS );

	_papi_hwi_system_info.hw_info.ncpu = win_hwinfo.ncpus;
	_papi_hwi_system_info.hw_info.nnodes = win_hwinfo.nnodes;
	_papi_hwi_system_info.hw_info.totalcpus = win_hwinfo.total_cpus;

	_papi_hwi_system_info.hw_info.vendor = win_hwinfo.vendor;
	_papi_hwi_system_info.hw_info.revision = ( float ) win_hwinfo.revision;
	strcpy( _papi_hwi_system_info.hw_info.vendor_string,
			win_hwinfo.vendor_string );

	/* initialize the model to something */
	_papi_hwi_system_info.hw_info.model = PERFCTR_X86_GENERIC;

	if ( IS_P3( &win_hwinfo ) || IS_P3_XEON( &win_hwinfo ) ||
		 IS_CELERON( &win_hwinfo ) )
		_papi_hwi_system_info.hw_info.model = PERFCTR_X86_INTEL_PIII;

	if ( IS_MOBILE( &win_hwinfo ) )
		_papi_hwi_system_info.hw_info.model = PERFCTR_X86_INTEL_PENTM;

	if ( IS_P4( &win_hwinfo ) ) {
		if ( win_hwinfo.model >= 2 )
			/* this is a guess for Pentium 4 Model 2 */
			_papi_hwi_system_info.hw_info.model = PERFCTR_X86_INTEL_P4M2;
		else
			_papi_hwi_system_info.hw_info.model = PERFCTR_X86_INTEL_P4;
	}

	if ( IS_AMDDURON( &win_hwinfo ) || IS_AMDATHLON( &win_hwinfo ) )
		_papi_hwi_system_info.hw_info.model = PERFCTR_X86_AMD_K7;

	strcpy( _papi_hwi_system_info.hw_info.model_string,
			win_hwinfo.model_string );

	_papi_hwi_system_info.num_cntrs = win_hwinfo.nrctr;
	_papi_hwi_system_info.num_gp_cntrs = _papi_hwi_system_info.num_cntrs;

	_papi_hwi_system_info.hw_info.mhz = ( float ) win_hwinfo.mhz;
	_papi_hwi_system_info.hw_info.clock_mhz = mhz;

	return ( PAPI_OK );
}
Ejemplo n.º 15
0
/**
 * goes through proc and tries to discover all mounted Lustre fs
 */
static int
init_lustre_counters( void  )
{
        char lustre_dir[PATH_MAX];
	char path[PATH_MAX];
	char path_readahead[PATH_MAX],path_stats[PATH_MAX];
	char *ptr;
	char fs_name[100];
	int idx = 0;
	int tmp_fd;
	DIR *proc_dir;
	struct dirent *entry;

	sprintf(lustre_dir,"%s/llite",proc_base_path);

	proc_dir = opendir( lustre_dir );
	if ( proc_dir == NULL ) {
	   SUBDBG("Cannot open %s\n",lustre_dir);
	   return PAPI_ESYS;
	}

	entry = readdir( proc_dir );

	while ( entry != NULL ) {
	   memset( path, 0, PATH_MAX );
	   snprintf( path, PATH_MAX - 1, "%s/%s/stats", lustre_dir,
				  entry->d_name );
	   SUBDBG("checking for file %s\n", path);

	   if ( ( tmp_fd = open( path, O_RDONLY ) ) != -1 ) {
	      close( tmp_fd );

	      /* erase \r and \n at the end of path */
	      /* why is this necessary?             */

	      idx = strlen( path );
	      idx--;

	      while ( path[idx] == '\r' || path[idx] == '\n' )
		    path[idx--] = 0;

	      /* Lustre paths are of type server-UUID */

	      idx = 0;

	      ptr = strstr(path,"llite/") + 6;

	      while ( *ptr && idx < 100 ) {
	         fs_name[idx] = *ptr;
		 ptr++;
		 idx++;
	      }

	      SUBDBG("found Lustre FS: %s\n", fs_name);

	      snprintf( path_stats, PATH_MAX - 1, 
			"%s/%s/stats", 
			lustre_dir,
			entry->d_name );
	      SUBDBG("Found file %s\n", path_stats);

	      snprintf( path_readahead, PATH_MAX - 1, 
			"%s/%s/read_ahead_stats", 
			lustre_dir,
			entry->d_name );
	      SUBDBG("Now checking for file %s\n", path_readahead);


	      strcpy( ptr, "read_ahead_stats" );
	      addLustreFS( fs_name, path_stats, path_readahead );

	   }
	   entry = readdir( proc_dir );
	}
	closedir( proc_dir );

	return PAPI_OK;

}
Ejemplo n.º 16
0
/* Assign the global native and preset table pointers, find the native
   table's size in memory and then call the preset setup routine. */
int
setup_x86_presets( int cputype )
{
	int retval = PAPI_OK;

        if ( ( retval = _papi_libpfm_init(&MY_VECTOR) ) != PAPI_OK ) {
	   return retval;
	}

	if ( is_pentium4() ) {
		/* load the baseline event map for all Pentium 4s */

		_papi_libpfm_setup_presets( "Intel Pentium4", 0 );	/* base events */

		/* fix up the floating point and vector ops */
		if ( ( retval = _papi_p4_hwd_fixup_fp(  ) ) != PAPI_OK )
			return ( retval );
		if ( ( retval = _papi_hwd_fixup_vec(  ) ) != PAPI_OK )
			return ( retval );

		/* install L3 cache events iff 3 levels of cache exist */
		if ( _papi_hwi_system_info.hw_info.mem_hierarchy.levels == 3 )
			_papi_libpfm_setup_presets( "Intel Pentium4 L3", 0 );

		/* overload with any model dependent events */
		if ( cputype == PERFCTR_X86_INTEL_P4 ) {
			/* do nothing besides the base map */
		} else if ( cputype == PERFCTR_X86_INTEL_P4M2 ) {
		}
#ifdef PERFCTR_X86_INTEL_P4M3
		else if ( cputype == PERFCTR_X86_INTEL_P4M3 ) {
		}
#endif
		else {
			PAPIERROR( MODEL_ERROR );
			return ( PAPI_ESBSTR );
		}
	} else {
		switch ( cputype ) {
		case PERFCTR_X86_GENERIC:
		case PERFCTR_X86_WINCHIP_C6:
		case PERFCTR_X86_WINCHIP_2:
		case PERFCTR_X86_VIA_C3:
		case PERFCTR_X86_INTEL_P5:
		case PERFCTR_X86_INTEL_P5MMX:
			SUBDBG( "This cpu is supported by the perfctr-x86 substrate\n" );
			PAPIERROR( MODEL_ERROR );
			return ( PAPI_ESBSTR );
		case PERFCTR_X86_INTEL_P6:
			_papi_libpfm_setup_presets( "Intel P6", 0 );	/* base events */
			break;
		case PERFCTR_X86_INTEL_PII:
			_papi_libpfm_setup_presets( "Intel P6", 0 );	/* base events */
			break;
		case PERFCTR_X86_INTEL_PIII:
			_papi_libpfm_setup_presets( "Intel P6", 0 );	/* base events */
			_papi_libpfm_setup_presets( "Intel PentiumIII", 0 );	/* events that differ from Pentium M */
			break;
#ifdef PERFCTR_X86_INTEL_PENTM
		case PERFCTR_X86_INTEL_PENTM:
			_papi_libpfm_setup_presets( "Intel P6", 0 );	/* base events */
			_papi_libpfm_setup_presets( "Intel PentiumM", 0 );	/* events that differ from PIII */
			break;
#endif
#ifdef PERFCTR_X86_INTEL_CORE
		case PERFCTR_X86_INTEL_CORE:
			_papi_libpfm_setup_presets( "Intel Core Duo/Solo", 0 );
			break;
#endif
#ifdef PERFCTR_X86_INTEL_CORE2
		case PERFCTR_X86_INTEL_CORE2:
			_papi_libpfm_setup_presets( "Intel Core2", 0 );
			break;
#endif
		case PERFCTR_X86_AMD_K7:
			_papi_libpfm_setup_presets( "AMD64 (K7)", 0 );
			break;
#ifdef PERFCTR_X86_AMD_K8	 /* this is defined in perfctr 2.5.x */
		case PERFCTR_X86_AMD_K8:
			_papi_libpfm_setup_presets( "AMD64", 0 );
			_papi_hwd_fixup_fp( "AMD64" );
			break;
#endif
#ifdef PERFCTR_X86_AMD_K8C	 /* this is defined in perfctr 2.6.x */
		case PERFCTR_X86_AMD_K8C:
			_papi_libpfm_setup_presets( "AMD64", 0 );
			_papi_hwd_fixup_fp( "AMD64" );
			break;
#endif
#ifdef PERFCTR_X86_AMD_FAM10 /* this is defined in perfctr 2.6.29 */
		case PERFCTR_X86_AMD_FAM10:
			_papi_libpfm_setup_presets( "AMD64 (Barcelona)", 0 );
			break;
#endif
#ifdef PERFCTR_X86_INTEL_ATOM	/* family 6 model 28 */
		case PERFCTR_X86_INTEL_ATOM:
			_papi_libpfm_setup_presets( "Intel Atom", 0 );
			break;
#endif
#ifdef PERFCTR_X86_INTEL_NHLM	/* family 6 model 26 */
		case PERFCTR_X86_INTEL_NHLM:
			_papi_libpfm_setup_presets( "Intel Nehalem", 0 );
			break;
#endif
#ifdef PERFCTR_X86_INTEL_WSTMR
		case PERFCTR_X86_INTEL_WSTMR:
			_papi_libpfm_setup_presets( "Intel Westmere", 0 );
			break;
#endif
		default:
			PAPIERROR( MODEL_ERROR );
			return PAPI_ESBSTR;
		}
		SUBDBG( "Number of native events: %d\n",
				MY_VECTOR.cmp_info.num_native_events );
	}
	return retval;
}
Ejemplo n.º 17
0
/* From niagara2 code */
int
_solaris_update_shlib_info( papi_mdi_t *mdi )
{
	char *file = "/proc/self/map";
	char *resolve_pattern = "/proc/self/path/%s";

	char lastobject[PRMAPSZ];
	char link[PAPI_HUGE_STR_LEN];
	char path[PAPI_HUGE_STR_LEN];

	prmap_t mapping;

	int fd, count = 0, total = 0, position = -1, first = 1;
	caddr_t t_min, t_max, d_min, d_max;

	PAPI_address_map_t *pam, *cur;

#ifdef DEBUG
	SUBDBG( "ENTERING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
			__LINE__ );
#endif

	fd = open( file, O_RDONLY );

	if ( fd == -1 ) {
		return PAPI_ESYS;
	}

	memset( lastobject, 0, PRMAPSZ );

#ifdef DEBUG
	SUBDBG( " -> %s: Preprocessing memory maps from procfs\n", __func__ );
#endif

	/* Search through the list of mappings in order to identify a) how many
	   mappings are available and b) how many unique mappings are available. */
	while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {
#ifdef DEBUG
		SUBDBG( " -> %s: Found a new memory map entry\n", __func__ );
#endif
		/* Another entry found, just the total count of entries. */
		total++;

		/* Is the mapping accessible and not anonymous? */
		if ( mapping.pr_mflags & ( MA_READ | MA_WRITE | MA_EXEC ) &&
			 !( mapping.pr_mflags & MA_ANON ) ) {
			/* Test if a new library has been found. If a new library has been
			   found a new entry needs to be counted. */
			if ( strcmp( lastobject, mapping.pr_mapname ) != 0 ) {
				strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
				count++;

#ifdef DEBUG
				SUBDBG( " -> %s: Memory mapping entry valid for %s\n", __func__,
						mapping.pr_mapname );
#endif
			}
		}
	}
#ifdef DEBUG
	SUBDBG( " -> %s: Preprocessing done, starting to analyze\n", __func__ );
#endif


	/* Start from the beginning, now fill in the found mappings */
	if ( lseek( fd, 0, SEEK_SET ) == -1 ) {
		return PAPI_ESYS;
	}

	memset( lastobject, 0, PRMAPSZ );

	/* Allocate memory */
	pam =
		( PAPI_address_map_t * ) papi_calloc( count,
											  sizeof ( PAPI_address_map_t ) );

	while ( read( fd, &mapping, sizeof ( prmap_t ) ) > 0 ) {

		if ( mapping.pr_mflags & MA_ANON ) {
#ifdef DEBUG
			SUBDBG
				( " -> %s: Anonymous mapping (MA_ANON) found for %s, skipping\n",
				  __func__, mapping.pr_mapname );
#endif
			continue;
		}

		/* Check for a new entry */
		if ( strcmp( mapping.pr_mapname, lastobject ) != 0 ) {
#ifdef DEBUG
			SUBDBG( " -> %s: Analyzing mapping for %s\n", __func__,
					mapping.pr_mapname );
#endif
			cur = &( pam[++position] );
			strncpy( lastobject, mapping.pr_mapname, PRMAPSZ );
			snprintf( link, PAPI_HUGE_STR_LEN, resolve_pattern, lastobject );
			memset( path, 0, PAPI_HUGE_STR_LEN );
			readlink( link, path, PAPI_HUGE_STR_LEN );
			strncpy( cur->name, path, PAPI_HUGE_STR_LEN );
#ifdef DEBUG
			SUBDBG( " -> %s: Resolved name for %s: %s\n", __func__,
					mapping.pr_mapname, cur->name );
#endif
		}

		if ( mapping.pr_mflags & MA_READ ) {
			/* Data (MA_WRITE) or text (MA_READ) segment? */
			if ( mapping.pr_mflags & MA_WRITE ) {
				cur->data_start = ( caddr_t ) mapping.pr_vaddr;
				cur->data_end =
					( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );

				if ( strcmp
					 ( cur->name,
					   _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
					_papi_hwi_system_info.exe_info.address_info.data_start =
						cur->data_start;
					_papi_hwi_system_info.exe_info.address_info.data_end =
						cur->data_end;
				}

				if ( first )
					d_min = cur->data_start;
				if ( first )
					d_max = cur->data_end;

				if ( cur->data_start < d_min ) {
					d_min = cur->data_start;
				}

				if ( cur->data_end > d_max ) {
					d_max = cur->data_end;
				}
			} else if ( mapping.pr_mflags & MA_EXEC ) {
				cur->text_start = ( caddr_t ) mapping.pr_vaddr;
				cur->text_end =
					( caddr_t ) ( mapping.pr_vaddr + mapping.pr_size );

				if ( strcmp
					 ( cur->name,
					   _papi_hwi_system_info.exe_info.fullname ) == 0 ) {
					_papi_hwi_system_info.exe_info.address_info.text_start =
						cur->text_start;
					_papi_hwi_system_info.exe_info.address_info.text_end =
						cur->text_end;
				}

				if ( first )
					t_min = cur->text_start;
				if ( first )
					t_max = cur->text_end;

				if ( cur->text_start < t_min ) {
					t_min = cur->text_start;
				}

				if ( cur->text_end > t_max ) {
					t_max = cur->text_end;
				}
			}
		}

		first = 0;
	}

	close( fd );

	/* During the walk of shared objects the upper and lower bound of the
	   segments could be discovered. The bounds are stored in the PAPI info
	   structure. The information is important for the profiling functions of
	   PAPI. */

/* This variant would pass the addresses of all text and data segments 
  _papi_hwi_system_info.exe_info.address_info.text_start = t_min;
  _papi_hwi_system_info.exe_info.address_info.text_end = t_max;
  _papi_hwi_system_info.exe_info.address_info.data_start = d_min;
  _papi_hwi_system_info.exe_info.address_info.data_end = d_max;
*/

#ifdef DEBUG
	SUBDBG( " -> %s: Analysis of memory maps done, results:\n", __func__ );
	SUBDBG( " -> %s: text_start=%#x, text_end=%#x, text_size=%lld\n", __func__,
			_papi_hwi_system_info.exe_info.address_info.text_start,
			_papi_hwi_system_info.exe_info.address_info.text_end,
			_papi_hwi_system_info.exe_info.address_info.text_end
			- _papi_hwi_system_info.exe_info.address_info.text_start );
	SUBDBG( " -> %s: data_start=%#x, data_end=%#x, data_size=%lld\n", __func__,
			_papi_hwi_system_info.exe_info.address_info.data_start,
			_papi_hwi_system_info.exe_info.address_info.data_end,
			_papi_hwi_system_info.exe_info.address_info.data_end
			- _papi_hwi_system_info.exe_info.address_info.data_start );
#endif

	/* Store the map read and the total count of shlibs found */
	_papi_hwi_system_info.shlib_info.map = pam;
	_papi_hwi_system_info.shlib_info.count = count;

#ifdef DEBUG
	SUBDBG( "LEAVING FUNCTION  >>%s<< at %s:%d\n", __func__, __FILE__,
			__LINE__ );
#endif

	return PAPI_OK;
}
Ejemplo n.º 18
0
static int
_x86_init_control_state( hwd_control_state_t * ptr )
{
	int i, def_mode = 0;

	if ( is_pentium4() ) {
		if ( MY_VECTOR.cmp_info.default_domain & PAPI_DOM_USER )
			def_mode |= ESCR_T0_USR;
		if ( MY_VECTOR.cmp_info.default_domain & PAPI_DOM_KERNEL )
			def_mode |= ESCR_T0_OS;

		for ( i = 0; i < MY_VECTOR.cmp_info.num_cntrs; i++ ) {
			ptr->control.cpu_control.evntsel_aux[i] |= def_mode;
		}
		ptr->control.cpu_control.tsc_on = 1;
		ptr->control.cpu_control.nractrs = 0;
		ptr->control.cpu_control.nrictrs = 0;

#ifdef VPERFCTR_CONTROL_CLOEXEC
		ptr->control.flags = VPERFCTR_CONTROL_CLOEXEC;
		SUBDBG( "close on exec\t\t\t%u\n", ptr->control.flags );
#endif
	} else {

		if ( MY_VECTOR.cmp_info.default_domain & PAPI_DOM_USER )
			def_mode |= PERF_USR;
		if ( MY_VECTOR.cmp_info.default_domain & PAPI_DOM_KERNEL )
			def_mode |= PERF_OS;

		ptr->allocated_registers.selector = 0;
		switch ( _papi_hwi_system_info.hw_info.model ) {
		case PERFCTR_X86_GENERIC:
		case PERFCTR_X86_WINCHIP_C6:
		case PERFCTR_X86_WINCHIP_2:
		case PERFCTR_X86_VIA_C3:
		case PERFCTR_X86_INTEL_P5:
		case PERFCTR_X86_INTEL_P5MMX:
		case PERFCTR_X86_INTEL_PII:
		case PERFCTR_X86_INTEL_P6:
		case PERFCTR_X86_INTEL_PIII:
#ifdef PERFCTR_X86_INTEL_CORE
		case PERFCTR_X86_INTEL_CORE:
#endif
#ifdef PERFCTR_X86_INTEL_PENTM
		case PERFCTR_X86_INTEL_PENTM:
#endif
			ptr->control.cpu_control.evntsel[0] |= PERF_ENABLE;
			for ( i = 0; i < MY_VECTOR.cmp_info.num_cntrs; i++ ) {
				ptr->control.cpu_control.evntsel[i] |= def_mode;
				ptr->control.cpu_control.pmc_map[i] = ( unsigned int ) i;
			}
			break;
#ifdef PERFCTR_X86_INTEL_CORE2
		case PERFCTR_X86_INTEL_CORE2:
#endif
#ifdef PERFCTR_X86_INTEL_ATOM
		case PERFCTR_X86_INTEL_ATOM:
#endif
#ifdef PERFCTR_X86_INTEL_NHLM
		case PERFCTR_X86_INTEL_NHLM:
#endif
#ifdef PERFCTR_X86_INTEL_WSTMR
		case PERFCTR_X86_INTEL_WSTMR:
#endif
#ifdef PERFCTR_X86_AMD_K8
		case PERFCTR_X86_AMD_K8:
#endif
#ifdef PERFCTR_X86_AMD_K8C
		case PERFCTR_X86_AMD_K8C:
#endif
#ifdef PERFCTR_X86_AMD_FAM10H	/* this is defined in perfctr 2.6.29 */
		case PERFCTR_X86_AMD_FAM10H:
#endif
		case PERFCTR_X86_AMD_K7:
			for ( i = 0; i < MY_VECTOR.cmp_info.num_cntrs; i++ ) {
				ptr->control.cpu_control.evntsel[i] |= PERF_ENABLE | def_mode;
				ptr->control.cpu_control.pmc_map[i] = ( unsigned int ) i;
			}
			break;
		}
#ifdef VPERFCTR_CONTROL_CLOEXEC
		ptr->control.flags = VPERFCTR_CONTROL_CLOEXEC;
		SUBDBG( "close on exec\t\t\t%u\n", ptr->control.flags );
#endif

		/* Make sure the TSC is always on */
		ptr->control.cpu_control.tsc_on = 1;
	}
	return ( PAPI_OK );
}
Ejemplo n.º 19
0
int
_solaris_get_system_info( papi_mdi_t *mdi )
{
	int retval;
	pid_t pid;
	char maxargs[PAPI_MAX_STR_LEN] = "<none>";
	psinfo_t psi;
	int fd;
	int hz, version;
	char cpuname[PAPI_MAX_STR_LEN], pname[PAPI_HUGE_STR_LEN];

	/* Check counter access */

	if ( cpc_version( CPC_VER_CURRENT ) != CPC_VER_CURRENT )
		return PAPI_ECMP;
	SUBDBG( "CPC version %d successfully opened\n", CPC_VER_CURRENT );

	if ( cpc_access(  ) == -1 )
		return PAPI_ECMP;

	/* Global variable cpuver */

	cpuver = cpc_getcpuver(  );
	SUBDBG( "Got %d from cpc_getcpuver()\n", cpuver );
	if ( cpuver == -1 )
		return PAPI_ECMP;

#ifdef DEBUG
	{
		if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
			const char *name;
			int i;

			name = cpc_getcpuref( cpuver );
			if ( name ) {
				SUBDBG( "CPC CPU reference: %s\n", name );
			}
			else {
				SUBDBG( "Could not get a CPC CPU reference\n" );
			}

			for ( i = 0; i < cpc_getnpic( cpuver ); i++ ) {
				SUBDBG( "\n%6s %-40s %8s\n", "Reg", "Symbolic name", "Code" );
				cpc_walk_names( cpuver, i, "%6d %-40s %02x\n",
								print_walk_names );
			}
			SUBDBG( "\n" );
		}
	}
#endif


	/* Initialize other globals */

	if ( ( retval = build_tables(  ) ) != PAPI_OK )
		return retval;

	preset_search_map = preset_table;
	if ( cpuver <= CPC_ULTRA2 ) {
		SUBDBG( "cpuver (==%d) <= CPC_ULTRA2 (==%d)\n", cpuver, CPC_ULTRA2 );
		pcr_shift[0] = CPC_ULTRA_PCR_PIC0_SHIFT;
		pcr_shift[1] = CPC_ULTRA_PCR_PIC1_SHIFT;
	} else if ( cpuver <= LASTULTRA3 ) {
		SUBDBG( "cpuver (==%d) <= CPC_ULTRA3x (==%d)\n", cpuver, LASTULTRA3 );
		pcr_shift[0] = CPC_ULTRA_PCR_PIC0_SHIFT;
		pcr_shift[1] = CPC_ULTRA_PCR_PIC1_SHIFT;
		_solaris_vector.cmp_info.hardware_intr = 1;
		_solaris_vector.cmp_info.hardware_intr_sig = SIGEMT;
	} else
		return PAPI_ECMP;

	/* Path and args */

	pid = getpid(  );
	if ( pid == -1 )
		return ( PAPI_ESYS );

	/* Turn on microstate accounting for this process and any LWPs. */

	sprintf( maxargs, "/proc/%d/ctl", ( int ) pid );
	if ( ( fd = open( maxargs, O_WRONLY ) ) == -1 )
		return ( PAPI_ESYS );
	{
		int retval;
		struct
		{
			long cmd;
			long flags;
		} cmd;
		cmd.cmd = PCSET;
		cmd.flags = PR_MSACCT | PR_MSFORK;
		retval = write( fd, &cmd, sizeof ( cmd ) );
		close( fd );
		SUBDBG( "Write PCSET returned %d\n", retval );
		if ( retval != sizeof ( cmd ) )
			return ( PAPI_ESYS );
	}

	/* Get executable info */

	sprintf( maxargs, "/proc/%d/psinfo", ( int ) pid );
	if ( ( fd = open( maxargs, O_RDONLY ) ) == -1 )
		return ( PAPI_ESYS );
	read( fd, &psi, sizeof ( psi ) );
	close( fd );

	/* Cut off any arguments to exe */
	{
		char *tmp;
		tmp = strchr( psi.pr_psargs, ' ' );
		if ( tmp != NULL )
			*tmp = '\0';
	}

	if ( realpath( psi.pr_psargs, pname ) )
		strncpy( _papi_hwi_system_info.exe_info.fullname, pname,
				 PAPI_HUGE_STR_LEN );
	else
		strncpy( _papi_hwi_system_info.exe_info.fullname, psi.pr_psargs,
				 PAPI_HUGE_STR_LEN );

	/* please don't use pr_fname here, because it can only store less that 
	   16 characters */
	strcpy( _papi_hwi_system_info.exe_info.address_info.name,
			basename( _papi_hwi_system_info.exe_info.fullname ) );

	SUBDBG( "Full Executable is %s\n",
			_papi_hwi_system_info.exe_info.fullname );

	/* Executable regions, reading /proc/pid/maps file */
	retval = _ultra_hwd_update_shlib_info( &_papi_hwi_system_info );

	/* Hardware info */

	_papi_hwi_system_info.hw_info.ncpu = sysconf( _SC_NPROCESSORS_ONLN );
	_papi_hwi_system_info.hw_info.nnodes = 1;
	_papi_hwi_system_info.hw_info.totalcpus = sysconf( _SC_NPROCESSORS_CONF );

	retval = scan_prtconf( cpuname, PAPI_MAX_STR_LEN, &hz, &version );
	if ( retval == -1 )
		return PAPI_ECMP;

	strcpy( _papi_hwi_system_info.hw_info.model_string,
			cpc_getcciname( cpuver ) );
	_papi_hwi_system_info.hw_info.model = cpuver;
	strcpy( _papi_hwi_system_info.hw_info.vendor_string, "SUN" );
	_papi_hwi_system_info.hw_info.vendor = PAPI_VENDOR_SUN;
	_papi_hwi_system_info.hw_info.revision = version;

	_papi_hwi_system_info.hw_info.mhz = ( ( float ) hz / 1.0e6 );
	SUBDBG( "hw_info.mhz = %f\n", _papi_hwi_system_info.hw_info.mhz );

	_papi_hwi_system_info.hw_info.cpu_max_mhz = _papi_hwi_system_info.hw_info.mhz;
	_papi_hwi_system_info.hw_info.cpu_min_mhz = _papi_hwi_system_info.hw_info.mhz;


	/* Number of PMCs */

	retval = cpc_getnpic( cpuver );
	if ( retval < 0 )
		return PAPI_ECMP;

	_solaris_vector.cmp_info.num_cntrs = retval;
	_solaris_vector.cmp_info.fast_real_timer = 1;
	_solaris_vector.cmp_info.fast_virtual_timer = 1;
	_solaris_vector.cmp_info.default_domain = PAPI_DOM_USER;
	_solaris_vector.cmp_info.available_domains =
		PAPI_DOM_USER | PAPI_DOM_KERNEL;

	/* Setup presets */

	retval = _papi_hwi_setup_all_presets( preset_search_map, NULL );
	if ( retval )
		return ( retval );

	return ( PAPI_OK );
}
Ejemplo n.º 20
0
/* This function removes shared resources available to the src event
    from the resources available to the dst event,
    and reduces the rank of the dst event accordingly. Typically,
    the src event will be exclusive, but the code shouldn't assume it.
    Returns nothing.  */
static void
_x86_bpt_map_preempt( hwd_reg_alloc_t * dst, hwd_reg_alloc_t * src )
{
	int i;
	unsigned shared;

	if ( is_pentium4() ) {
#ifdef DEBUG
		SUBDBG( "src, dst\n" );
		print_alloc( src );
		print_alloc( dst );
#endif

		/* check for a pebs conflict */
		/* pebs enables must both be non-zero */
		i = ( ( ( dst->ra_bits.pebs_enable && src->ra_bits.pebs_enable ) &&
				/* and not equal to each other */
				( dst->ra_bits.pebs_enable != src->ra_bits.pebs_enable ) ) ||
			  /* same for pebs_matrix_vert */
			  ( ( dst->ra_bits.pebs_matrix_vert &&
				  src->ra_bits.pebs_matrix_vert )
				&& ( dst->ra_bits.pebs_matrix_vert !=
					 src->ra_bits.pebs_matrix_vert ) ) );
		if ( i ) {
			SUBDBG( "pebs conflict! clearing selector\n" );
			dst->ra_selector = 0;
			return;
		} else {
			/* remove counters referenced by any shared escrs */
			if ( ( dst->ra_escr[0] == src->ra_escr[0] ) &&
				 ( ( int ) dst->ra_escr[0] != -1 ) ) {
				dst->ra_selector &= ~dst->ra_bits.counter[0];
				dst->ra_escr[0] = -1;
			}
			if ( ( dst->ra_escr[1] == src->ra_escr[1] ) &&
				 ( ( int ) dst->ra_escr[1] != -1 ) ) {
				dst->ra_selector &= ~dst->ra_bits.counter[1];
				dst->ra_escr[1] = -1;
			}

			/* remove any remaining shared counters */
			shared = ( dst->ra_selector & src->ra_selector );
			if ( shared )
				dst->ra_selector ^= shared;
		}
		/* recompute rank */
		for ( i = 0, dst->ra_rank = 0; i < MAX_COUNTERS; i++ )
			if ( dst->ra_selector & ( 1 << i ) )
				dst->ra_rank++;
#ifdef DEBUG
		SUBDBG( "new dst\n" );
		print_alloc( dst );
#endif
	} else {
		shared = dst->ra_selector & src->ra_selector;
		if ( shared )
			dst->ra_selector ^= shared;
		for ( i = 0, dst->ra_rank = 0; i < MAX_COUNTERS; i++ )
			if ( dst->ra_selector & ( 1 << i ) )
				dst->ra_rank++;
	}
}
Ejemplo n.º 21
0
static int
generate_preset_search_map( hwi_search_t ** maploc, hwi_dev_notes_t ** noteloc,
							pfm_preset_search_entry_t * strmap )
{

	int k = 0, term;
	unsigned int i = 0, j = 0;
	hwi_search_t *psmap;
	hwi_dev_notes_t *notemap;
	int event_idx;

	/* Count up the proposed presets */
	while ( strmap[i].preset ) {
	  i++;
	}

	SUBDBG( "generate_preset_search_map(%p,%p,%p) %d proposed presets\n",
			maploc, noteloc, strmap, i );
	i++;

	/* Add null entry */
	psmap = ( hwi_search_t * ) malloc( i * sizeof ( hwi_search_t ) );
	if ( psmap == NULL ) {
	   return PAPI_ENOMEM;
	}

	notemap = ( hwi_dev_notes_t * ) malloc( i * sizeof ( hwi_dev_notes_t ) );
	if ( notemap == NULL ) {
	   free(psmap);
	   return PAPI_ENOMEM;
	}

	memset( psmap, 0x0, i * sizeof ( hwi_search_t ) );
	memset( notemap, 0x0, i * sizeof ( hwi_dev_notes_t ) );

	i = 0;
	while ( strmap[i].preset ) {

	   /* Handle derived events */
	   term = 0;
	   do {
	      int ret;

	      SUBDBG("Looking up: %s\n",strmap[i].findme[term]);
	      ret=_papi_hwi_native_name_to_code(strmap[i].findme[term],
					     &event_idx);

	      if (ret==PAPI_OK) {
		 SUBDBG("Found %x\n",event_idx);
		 psmap[j].data.native[term]=event_idx;
		 term++;
	      }
	      else {
		 SUBDBG("Error finding event %x\n",event_idx);
		 break;
	      }

	   } while ( strmap[i].findme[term] != NULL &&
					  term < PAPI_MAX_COUNTER_TERMS );

	   /* terminate the native term array with PAPI_NULL */
	   if ( term < PAPI_MAX_COUNTER_TERMS ) {
	      psmap[j].data.native[term] = PAPI_NULL;
	   }

	   //if ( ret == PAPI_OK ) {
	      psmap[j].event_code = ( unsigned int ) strmap[i].preset;
	      psmap[j].data.derived = strmap[i].derived;
	      if ( strmap[i].derived == DERIVED_POSTFIX ) {
		 strncpy( psmap[j].data.operation, strmap[i].operation,
							 PAPI_MIN_STR_LEN );
	      }
	      if ( strmap[i].note ) {
		 notemap[k].event_code = ( unsigned int ) strmap[i].preset;
		 notemap[k].dev_note = strdup( strmap[i].note );
		 k++;
	      }
	      j++;
	      //}
	   i++;
	}
	if ( i != j ) {
		PAPIERROR( "%d of %d events in %s were not valid", i - j, i,
				   PAPI_EVENT_FILE );
	}
	SUBDBG( "generate_preset_search_map(%p,%p,%p) %d actual presets\n", maploc,
			noteloc, strmap, j );
	*maploc = psmap;
	*noteloc = notemap;

	return PAPI_OK;
}
Ejemplo n.º 22
0
/* Register allocation */
static int
_x86_allocate_registers( EventSetInfo_t * ESI )
{
	int i, j, natNum;
	hwd_reg_alloc_t event_list[MAX_COUNTERS];
	hwd_register_t *ptr;

	/* Initialize the local structure needed
	   for counter allocation and optimization. */
	natNum = ESI->NativeCount;

	if ( is_pentium4() )
		SUBDBG( "native event count: %d\n", natNum );

	for ( i = 0; i < natNum; i++ ) {
		/* retrieve the mapping information about this native event */
		_papi_libpfm_ntv_code_to_bits( ( unsigned int ) ESI->NativeInfoArray[i].
							   ni_event, &event_list[i].ra_bits );

		if ( is_pentium4() ) {
			/* combine counter bit masks for both esc registers into selector */
			event_list[i].ra_selector =
				event_list[i].ra_bits.counter[0] | event_list[i].ra_bits.
				counter[1];
		} else {
			/* make sure register allocator only looks at legal registers */
			event_list[i].ra_selector =
				event_list[i].ra_bits.selector & ALLCNTRS;
#ifdef PERFCTR_X86_INTEL_CORE2
			if ( _papi_hwi_system_info.hw_info.model ==
				 PERFCTR_X86_INTEL_CORE2 )
				event_list[i].ra_selector |=
					( ( event_list[i].ra_bits.
						selector >> 16 ) << 2 ) & ALLCNTRS;
#endif
		}
		/* calculate native event rank, which is no. of counters it can live on */
		event_list[i].ra_rank = 0;
		for ( j = 0; j < MAX_COUNTERS; j++ ) {
			if ( event_list[i].ra_selector & ( 1 << j ) ) {
				event_list[i].ra_rank++;
			}
		}

		if ( is_pentium4() ) {
			event_list[i].ra_escr[0] = event_list[i].ra_bits.escr[0];
			event_list[i].ra_escr[1] = event_list[i].ra_bits.escr[1];
#ifdef DEBUG
			SUBDBG( "i: %d\n", i );
			print_alloc( &event_list[i] );
#endif
		}
	}
	if ( _papi_hwi_bipartite_alloc( event_list, natNum, ESI->CmpIdx ) ) {	/* successfully mapped */
		for ( i = 0; i < natNum; i++ ) {
#ifdef PERFCTR_X86_INTEL_CORE2
			if ( _papi_hwi_system_info.hw_info.model ==
				 PERFCTR_X86_INTEL_CORE2 )
				event_list[i].ra_bits.selector = event_list[i].ra_selector;
#endif
#ifdef DEBUG
			if ( is_pentium4() ) {
				SUBDBG( "i: %d\n", i );
				print_alloc( &event_list[i] );
			}
#endif
			/* Copy all info about this native event to the NativeInfo struct */
			ptr = ESI->NativeInfoArray[i].ni_bits;
			*ptr = event_list[i].ra_bits;

			if ( is_pentium4() ) {
				/* The selector contains the counter bit position. Turn it into a number
				   and store it in the first counter value, zeroing the second. */
				ptr->counter[0] = ffs( event_list[i].ra_selector ) - 1;
				ptr->counter[1] = 0;
			}

			/* Array order on perfctr is event ADD order, not counter #... */
			ESI->NativeInfoArray[i].ni_position = i;
		}
		return 1;
	} else
		return 0;
}
Ejemplo n.º 23
0
static int
read_net_counters( long long *values )
{
    FILE *fin;
    char line[NET_PROC_MAX_LINE];
    char *retval, *ifname, *data;
    int i, nf, if_bidx;

    fin = fopen(NET_PROC_FILE, "r");
    if (fin == NULL) {
        SUBDBG("Can't find %s, are you sure the /proc file-system is mounted?\n",
           NET_PROC_FILE);
        return NET_INVALID_RESULT;
    }

    /* skip the 2 header lines */
    for (i=0; i<2; i++) {
        retval = fgets (line, NET_PROC_MAX_LINE, fin);
        if (retval == NULL) {
            SUBDBG("Not enough lines in %s\n", NET_PROC_FILE);
			fclose(fin);
            return 0;
        }
    }

    while ((fgets (line, NET_PROC_MAX_LINE, fin)) == line) {

        /* split the interface name from its 16 counters */
        retval = strstr(line, ":");
        if (retval == NULL) {
            SUBDBG("Wrong line format <%s>\n", line);
            continue;
        }

        *retval = '\0';
        data = retval + 1;
        ifname = line;
        while (isspace(*ifname)) { ifname++; }

        if_bidx = getInterfaceBaseIndex(ifname);
        if (if_bidx < 0) {
            SUBDBG("Interface <%s> not found\n", ifname);
        } else {
            nf = sscanf( data,
                "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
                &values[if_bidx + 0],  &values[if_bidx + 1],
                &values[if_bidx + 2],  &values[if_bidx + 3],
                &values[if_bidx + 4],  &values[if_bidx + 5],
                &values[if_bidx + 6],  &values[if_bidx + 7],
                &values[if_bidx + 8],  &values[if_bidx + 9],
                &values[if_bidx + 10], &values[if_bidx + 11],
                &values[if_bidx + 12], &values[if_bidx + 13],
                &values[if_bidx + 14], &values[if_bidx + 15]);

            SUBDBG("\nRead "
                "%llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu %llu\n",
                values[if_bidx + 0],  values[if_bidx + 1],
                values[if_bidx + 2],  values[if_bidx + 3],
                values[if_bidx + 4],  values[if_bidx + 5],
                values[if_bidx + 6],  values[if_bidx + 7],
                values[if_bidx + 8],  values[if_bidx + 9],
                values[if_bidx + 10], values[if_bidx + 11],
                values[if_bidx + 12], values[if_bidx + 13],
                values[if_bidx + 14], values[if_bidx + 15]);

            if ( nf != NET_INTERFACE_COUNTERS ) {
                /* This shouldn't happen */
                SUBDBG("/proc line with wrong number of fields\n");
            }
        }

    }

    fclose(fin);

    return 0;
}
Ejemplo n.º 24
0
/* This function clears the current contents of the control structure and 
   updates it with whatever resources are allocated for all the native events
   in the native info structure array. */
static int
_x86_update_control_state( hwd_control_state_t * this_state,
						   NativeInfo_t * native, int count,
						   hwd_context_t * ctx )
{
	( void ) ctx;			 /*unused */
	unsigned int i, k, retval = PAPI_OK;
	hwd_register_t *bits;
	struct perfctr_cpu_control *cpu_control = &this_state->control.cpu_control;

	/* clear out the events from the control state */
	clear_cs_events( this_state );

	if ( is_pentium4() ) {
		/* fill the counters we're using */
		for ( i = 0; i < ( unsigned int ) count; i++ ) {
			/* dereference the mapping information about this native event */
			bits = native[i].ni_bits;

			/* Add counter control command values to eventset */
			cpu_control->pmc_map[i] = bits->counter[0];
			cpu_control->evntsel[i] = bits->cccr;
			cpu_control->ireset[i] = bits->ireset;
			cpu_control->pmc_map[i] |= FAST_RDPMC;
			cpu_control->evntsel_aux[i] |= bits->event;

			/* pebs_enable and pebs_matrix_vert are shared registers used for replay_events.
			   Replay_events count L1 and L2 cache events. There is only one of each for 
			   the entire eventset. Therefore, there can be only one unique replay_event 
			   per eventset. This means L1 and L2 can't be counted together. Which stinks.
			   This conflict should be trapped in the allocation scheme, but we'll test for it
			   here too, just in case. */
			if ( bits->pebs_enable ) {
				/* if pebs_enable isn't set, just copy */
				if ( cpu_control->p4.pebs_enable == 0 ) {
					cpu_control->p4.pebs_enable = bits->pebs_enable;
					/* if pebs_enable conflicts, flag an error */
				} else if ( cpu_control->p4.pebs_enable != bits->pebs_enable ) {
					SUBDBG
						( "WARNING: P4_update_control_state -- pebs_enable conflict!" );
					retval = PAPI_ECNFLCT;
				}
				/* if pebs_enable == bits->pebs_enable, do nothing */
			}
			if ( bits->pebs_matrix_vert ) {
				/* if pebs_matrix_vert isn't set, just copy */
				if ( cpu_control->p4.pebs_matrix_vert == 0 ) {
					cpu_control->p4.pebs_matrix_vert = bits->pebs_matrix_vert;
					/* if pebs_matrix_vert conflicts, flag an error */
				} else if ( cpu_control->p4.pebs_matrix_vert !=
							bits->pebs_matrix_vert ) {
					SUBDBG
						( "WARNING: P4_update_control_state -- pebs_matrix_vert conflict!" );
					retval = PAPI_ECNFLCT;
				}
				/* if pebs_matrix_vert == bits->pebs_matrix_vert, do nothing */
			}
		}
		this_state->control.cpu_control.nractrs = count;

		/* Make sure the TSC is always on */
		this_state->control.cpu_control.tsc_on = 1;

#ifdef DEBUG
		print_control( &this_state->control.cpu_control );
#endif
	} else {
		switch ( _papi_hwi_system_info.hw_info.model ) {
#ifdef PERFCTR_X86_INTEL_CORE2
		case PERFCTR_X86_INTEL_CORE2:
			/* fill the counters we're using */
			for ( i = 0; i < ( unsigned int ) count; i++ ) {
				for ( k = 0; k < MAX_COUNTERS; k++ )
					if ( native[i].ni_bits->selector & ( 1 << k ) ) {
						break;
					}
				if ( k > 1 )
					this_state->control.cpu_control.pmc_map[i] =
						( k - 2 ) | 0x40000000;
				else
					this_state->control.cpu_control.pmc_map[i] = k;

				/* Add counter control command values to eventset */
				this_state->control.cpu_control.evntsel[i] |=
					native[i].ni_bits->counter_cmd;
			}
			break;
#endif
		default:
			/* fill the counters we're using */
			for ( i = 0; i < ( unsigned int ) count; i++ ) {
				/* Add counter control command values to eventset */
				this_state->control.cpu_control.evntsel[i] |=
					native[i].ni_bits->counter_cmd;
			}
		}
		this_state->control.cpu_control.nractrs = ( unsigned int ) count;
	}
	return retval;
}
Ejemplo n.º 25
0
static void
dispatch_emt( int signal, siginfo_t * sip, void *arg )
{
	int event_counter;
	_papi_hwi_context_t ctx;
	caddr_t address;
	ctx.si = sip;
	ctx.ucontext = arg;
	SUBDBG( "%d, %p, %p\n", signal, sip, arg );

	if ( sip->si_code == EMT_CPCOVF ) {
		papi_cpc_event_t *sample;
		EventSetInfo_t *ESI;
		ThreadInfo_t *thread = NULL;
		int t, overflow_vector, readvalue;

		thread = _papi_hwi_lookup_thread( 0 );
		ESI = ( EventSetInfo_t * ) thread->running_eventset;
		int cidx = ESI->CmpIdx;

		if ( ( ESI == NULL ) || ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
			OVFDBG( "Either no eventset or eventset not set to overflow.\n" );
			return;
		}

		if ( ESI->master != thread ) {
			PAPIERROR
				( "eventset->thread 0x%lx vs. current thread 0x%lx mismatch",
				  ESI->master, thread );
			return;
		}

		event_counter = ESI->overflow.event_counter;
		sample = &( ESI->ctl_state->counter_cmd );

		/* GROSS! This is a hack to 'push' the correct values 
		   back into the hardware, such that when PAPI handles
		   the overflow and reads the values, it gets the correct ones.
		 */

		/* Find which HW counter overflowed */

		if ( ESI->EventInfoArray[ESI->overflow.EventIndex[0]].pos[0] == 0 )
			t = 0;
		else
			t = 1;

		if ( cpc_take_sample( &sample->cmd ) == -1 )
			return;
		if ( event_counter == 1 ) {
			/* only one event is set to be the overflow monitor */

			/* generate the overflow vector */
			overflow_vector = 1 << t;
			/* reset the threshold */
			sample->cmd.ce_pic[t] = UINT64_MAX - ESI->overflow.threshold[0];
		} else {
			/* two events are set to be the overflow monitors */
			overflow_vector = 0;
			readvalue = sample->cmd.ce_pic[0];
			if ( readvalue >= 0 ) {
				/* the first counter overflowed */

				/* generate the overflow vector */
				overflow_vector = 1;
				/* reset the threshold */
				if ( t == 0 )
					sample->cmd.ce_pic[0] =
						UINT64_MAX - ESI->overflow.threshold[0];
				else
					sample->cmd.ce_pic[0] =
						UINT64_MAX - ESI->overflow.threshold[1];
			}
			readvalue = sample->cmd.ce_pic[1];
			if ( readvalue >= 0 ) {
				/* the second counter overflowed */

				/* generate the overflow vector */
				overflow_vector ^= 1 << 1;
				/* reset the threshold */
				if ( t == 0 )
					sample->cmd.ce_pic[1] =
						UINT64_MAX - ESI->overflow.threshold[1];
				else
					sample->cmd.ce_pic[1] =
						UINT64_MAX - ESI->overflow.threshold[0];
			}
			SUBDBG( "overflow_vector, = %d\n", overflow_vector );
			/* something is wrong here */
			if ( overflow_vector == 0 ) {
				PAPIERROR( "BUG! overflow_vector is 0, dropping interrupt" );
				return;
			}
		}

		/* Call the regular overflow function in extras.c */
		if ( thread->running_eventset[cidx]->overflow.
			 flags & PAPI_OVERFLOW_FORCE_SW ) {
			address = GET_OVERFLOW_ADDRESS(ctx);
			_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL,
												overflow_vector, 0, &thread,
												cidx );
		} else {
			PAPIERROR( "Additional implementation needed in dispatch_emt!" );
		}

#if DEBUG
		dump_cmd( sample );
#endif
		/* push back the correct values and start counting again */
		if ( cpc_bind_event( &sample->cmd, sample->flags ) == -1 )
			return;
	} else {
		SUBDBG( "dispatch_emt() dropped, si_code = %d\n", sip->si_code );
		return;
	}
}
Ejemplo n.º 26
0
int
_linux_get_system_info( papi_mdi_t *mdi ) {

	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 ( (retval = readlink( maxargs, mdi->exe_info.fullname, PAPI_HUGE_STR_LEN-1 )) < 0 ) {
		PAPIERROR( "readlink(%s) returned < 0", maxargs );
		return PAPI_ESYS;
	}
   if (retval > PAPI_HUGE_STR_LEN-1)   retval=PAPI_HUGE_STR_LEN-1;
   mdi->exe_info.fullname[retval] = '\0';

	/* Careful, basename can modify it's argument */

	strcpy( maxargs, mdi->exe_info.fullname );

   strncpy( mdi->exe_info.address_info.name, basename( maxargs ), PAPI_HUGE_STR_LEN-1);
   mdi->exe_info.address_info.name[PAPI_HUGE_STR_LEN-1] = '\0';

	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;
}
Ejemplo n.º 27
0
static int
scan_prtconf( char *cpuname, int len_cpuname, int *hz, int *ver )
{
	/* This code courtesy of our friends in Germany. Thanks Rudolph Berrendorf! */
	/* See the PCL home page for the German version of PAPI. */
	/* Modified by Nils Smeds, all new bugs are my fault */
	/*    The routine now looks for the first "Node" with the following: */
	/*           "device_type"     = 'cpu'                    */
	/*           "name"            = (Any value)              */
	/*           "sparc-version"   = (Any value)              */
	/*           "clock-frequency" = (Any value)              */
	int ihz, version;
	char line[256], cmd[80], name[256];
	FILE *f = NULL;
	char cmd_line[PAPI_HUGE_STR_LEN + PAPI_HUGE_STR_LEN], fname[L_tmpnam];
	unsigned int matched;

	/*??? system call takes very long */
	/* get system configuration and put output into file */

	tmpnam( fname );
	SUBDBG( "Temporary name %s\n", fname );

	sprintf( cmd_line, "/usr/sbin/prtconf -vp > %s", fname );
	SUBDBG( "Executing %s\n", cmd_line );
	if ( system( cmd_line ) == -1 ) {
		remove( fname );
		return -1;
	}

	f = fopen( fname, "r" );
	/* open output file */
	if ( f == NULL ) {
		remove( fname );
		return -1;
	}

	/* ignore all lines until we reach something with a sparc line */
	matched = 0x0;
	ihz = -1;
	while ( fgets( line, 256, f ) != NULL ) {
		/*SUBDBG(">>> %s",line); */
		if ( ( sscanf( line, "%s", cmd ) == 1 )
			 && strstr( line, "Node 0x" ) ) {
			matched = 0x0;
			/*SUBDBG("Found 'Node' -- search reset. (0x%2.2x)\n",matched); */
		} else {
			if ( strstr( cmd, "device_type:" ) && strstr( line, "'cpu'" ) ) {
				matched |= 0x1;
				SUBDBG( "Found 'cpu'. (0x%2.2x)\n", matched );
			} else if ( !strcmp( cmd, "sparc-version:" ) &&
						( sscanf( line, "%s %x", cmd, &version ) == 2 ) ) {
				matched |= 0x2;
				SUBDBG( "Found version=%d. (0x%2.2x)\n", version, matched );
			} else if ( !strcmp( cmd, "clock-frequency:" ) &&
						( sscanf( line, "%s %x", cmd, &ihz ) == 2 ) ) {
				matched |= 0x4;
				SUBDBG( "Found ihz=%d. (0x%2.2x)\n", ihz, matched );
			} else if ( !strcmp( cmd, "name:" ) &&
						( sscanf( line, "%s %s", cmd, name ) == 2 ) ) {
				matched |= 0x8;
				SUBDBG( "Found name: %s. (0x%2.2x)\n", name, matched );
			}
		}
		if ( ( matched & 0xF ) == 0xF )
			break;
	}
	SUBDBG( "Parsing found name=%s, speed=%dHz, version=%d\n", name, ihz,
			version );

	if ( matched ^ 0x0F )
		ihz = -1;
	else {
		*hz = ( float ) ihz;
		*ver = version;
		strncpy( cpuname, name, len_cpuname );
	}

	return ihz;

	/* End stolen code */
}
Ejemplo n.º 28
0
static int
papi_load_derived_events (char *pmu_str, int pmu_type, int cidx, int preset_flag) {
	SUBDBG( "ENTER: pmu_str: %s, pmu_type: %d, cidx: %d, preset_flag: %d\n", pmu_str, pmu_type, cidx, preset_flag);

	char pmu_name[PAPI_MIN_STR_LEN];
	char line[LINE_MAX];
	char name[PATH_MAX] = "builtin papi_events_table";
	char *event_file_path=NULL;
	char *event_table_ptr=NULL;
	int event_type_bits = 0;
	char *tmpn;
	char *tok_save_ptr=NULL;
	FILE *event_file = NULL;
	hwi_presets_t *results=NULL;
	int result_size = 0;
	int *event_count = NULL;
	int invalid_event;
	int line_no = 0;  /* count of lines read from event definition input */
	int derived = 0;
	int res_idx = 0;  /* index into results array for where to store next event */
	int preset = 0;
	int get_events = 0; /* only process derived events after CPU type they apply to is identified      */
	int found_events = 0; /* flag to track if event definitions (PRESETS) are found since last CPU declaration */
#ifdef PAPI_DATADIR
		char path[PATH_MAX];
#endif


	if (preset_flag) {
		/* try the environment variable first */
		if ((tmpn = getenv("PAPI_CSV_EVENT_FILE")) && (strlen(tmpn) > 0)) {
			event_file_path = tmpn;
		}
		/* if no valid environment variable, look for built-in table */
		else if (papi_events_table) {
			event_table_ptr = papi_events_table;
		}
		/* if no env var and no built-in, search for default file */
		else {
#ifdef PAPI_DATADIR
			sprintf( path, "%s/%s", PAPI_DATADIR, PAPI_EVENT_FILE );
			event_file_path = path;
#else
			event_file_path = PAPI_EVENT_FILE;
#endif
		}
		event_type_bits = PAPI_PRESET_MASK;
		results = &_papi_hwi_presets[0];
		result_size = PAPI_MAX_PRESET_EVENTS;
		event_count = &_papi_hwd[cidx]->cmp_info.num_preset_events;
	} else {
		if ((event_file_path = getenv( "PAPI_USER_EVENTS_FILE" )) == NULL ) {
			SUBDBG("EXIT: User event definition file not provided.\n");
			return PAPI_OK;
		}

		event_type_bits = PAPI_UE_MASK;
		results = &user_defined_events[0];
		result_size = PAPI_MAX_USER_EVENTS;
		event_count = &user_defined_events_count;
	}

	// if we have an event file pathname, open it and read event definitions from the file
	if (event_file_path != NULL) {
		if ((event_file = open_event_table(event_file_path)) == NULL) {
			// if file open fails, return an error
			SUBDBG("EXIT: Event file open failed.\n");
			return PAPI_ESYS;
		}
		strncpy(name, event_file_path, sizeof(name)-1);
		name[sizeof(name)-1] = '\0';
	} else if (event_table_ptr == NULL) {
		// if we do not have a path name or table pointer, return an error
		SUBDBG("EXIT: Both event_file_path and event_table_ptr are NULL.\n");
		return PAPI_ESYS;
	}

	/* copy the pmu identifier, stripping commas if found */
	tmpn = pmu_name;
	while (*pmu_str) {
		if (*pmu_str != ',')
			*tmpn++ = *pmu_str;
		pmu_str++;
	}
	*tmpn = '\0';

	/* at this point we have either a valid file pointer or built-in table pointer */
	while (get_event_line(line, event_file, &event_table_ptr)) {
		char *t;
		int i;

		// increment number of lines we have read
		line_no++;

		t = trim_string(strtok_r(line, ",", &tok_save_ptr));

		/* Skip blank lines */
		if ((t == NULL) || (strlen(t) == 0))
			continue;

		/* Skip comments */
		if (t[0] == '#') {
			continue;
		}

		if (strcasecmp(t, "CPU") == 0) {
			if (get_events != 0 && found_events != 0) {
				SUBDBG( "Ending event scanning at line %d of %s.\n", line_no, name);
				get_events = 0;
				found_events = 0;
			}

			t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
			if ((t == NULL) || (strlen(t) == 0)) {
				PAPIERROR("Expected name after CPU token at line %d of %s -- ignoring", line_no, name);
				continue;
			}

			if (strcasecmp(t, pmu_name) == 0) {
				int type;

				SUBDBG( "Process events for PMU %s found at line %d of %s.\n", t, line_no, name);

				t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
				if ((t == NULL) || (strlen(t) == 0)) {
					SUBDBG("No additional qualifier found, matching on string.\n");
					get_events = 1;
				} else if ((sscanf(t, "%d", &type) == 1) && (type == pmu_type)) {
					SUBDBG( "Found CPU %s type %d at line %d of %s.\n", pmu_name, type, line_no, name);
					get_events = 1;
				} else {
					SUBDBG( "Additional qualifier match failed %d vs %d.\n", pmu_type, type);
				}
			}
			continue;
		}

		if ((strcasecmp(t, "PRESET") == 0)  || (strcasecmp(t, "EVENT") == 0)) {

			if (get_events == 0)
				continue;

			found_events = 1;
			t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));

			if ((t == NULL) || (strlen(t) == 0)) {
				PAPIERROR("Expected name after PRESET token at line %d of %s -- ignoring", line_no, name);
				continue;
			}

			SUBDBG( "Examining event %s\n", t);

			// see if this event already exists in the results array, if not already known it sets up event in unused entry
			if ((res_idx = find_event_index (results, result_size, t)) < 0) {
				PAPIERROR("No room left for event %s -- ignoring", t);
				continue;
			}

			// add the proper event bits (preset or user defined bits)
			preset = res_idx | event_type_bits;

			SUBDBG( "Use event code: %#x for %s\n", preset, t);

			t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
			if ((t == NULL) || (strlen(t) == 0)) {
				// got an error, make this entry unused
				papi_free (results[res_idx].symbol);
				results[res_idx].symbol = NULL;
				PAPIERROR("Expected derived type after PRESET token at line %d of %s -- ignoring", line_no, name);
				continue;
			}

			if (_papi_hwi_derived_type(t, &derived) != PAPI_OK) {
				// got an error, make this entry unused
				papi_free (results[res_idx].symbol);
				results[res_idx].symbol = NULL;
				PAPIERROR("Invalid derived name %s after PRESET token at line %d of %s -- ignoring", t, line_no, name);
				continue;
			}

			/****************************************/
			/* Have an event, let's start assigning */
			/****************************************/

			SUBDBG( "Adding event: %s, code: %#x, derived: %d results[%d]: %p.\n", t, preset, derived, res_idx, &results[res_idx]);

			/* results[res_idx].event_code = preset; */
			results[res_idx].derived_int = derived;

			/* Derived support starts here */
			/* Special handling for postfix and infix */
			if ((derived == DERIVED_POSTFIX)  || (derived == DERIVED_INFIX)) {
				t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
				if ((t == NULL) || (strlen(t) == 0)) {
					// got an error, make this entry unused
					papi_free (results[res_idx].symbol);
					results[res_idx].symbol = NULL;
					PAPIERROR("Expected Operation string after derived type DERIVED_POSTFIX or DERIVED_INFIX at line %d of %s -- ignoring", line_no, name);
					continue;
				}

				// if it is an algebraic formula, we need to convert it to postfix
				if (derived == DERIVED_INFIX) {
					SUBDBG( "Converting InFix operations %s\n", t);
					t = infix_to_postfix( t );
					results[res_idx].derived_int = DERIVED_POSTFIX;
				}

				SUBDBG( "Saving PostFix operations %s\n", t);
				results[res_idx].postfix = papi_strdup(t);
			}

			/* All derived terms collected here */
			i = 0;
			invalid_event = 0;
			results[res_idx].count = 0;
			do {
				t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
				if ((t == NULL) || (strlen(t) == 0))
					break;
				if (strcasecmp(t, "NOTE") == 0)
					break;
				if (strcasecmp(t, "LDESC") == 0)
					break;
				if (strcasecmp(t, "SDESC") == 0)
					break;

				SUBDBG( "Adding term (%d) %s to derived event %#x, current native event count: %d.\n", i, t, preset, results[res_idx].count);

				// show that we do not have an event code yet (the component may create one and update this info)
				// this also clears any values left over from a previous call
				_papi_hwi_set_papi_event_code(-1, -1);

				// make sure that this term in the derived event is a valid event name
				// this call replaces preset and user event names with the equivalent native events in our results table
				// it also updates formulas for derived events so that they refer to the correct native event index
				if (is_event(t, results[res_idx].derived_int, &results[res_idx], i) == 0) {
					invalid_event = 1;
					PAPIERROR("Error finding event %s, it is used in derived event %s", t, results[res_idx].symbol);
					break;
				}

				i++;
			} while (results[res_idx].count < PAPI_EVENTS_IN_DERIVED_EVENT);

			/* preset code list must be PAPI_NULL terminated */
			if (i < PAPI_EVENTS_IN_DERIVED_EVENT) {
				results[res_idx].code[results[res_idx].count] = PAPI_NULL;
			}

			if (invalid_event) {
				// got an error, make this entry unused
				papi_free (results[res_idx].symbol);
				results[res_idx].symbol = NULL;
				continue;
			}

			/* End of derived support */

			// if we did not find any terms to base this derived event on, report error
			if (i == 0) {
				// got an error, make this entry unused
				papi_free (results[res_idx].symbol);
				results[res_idx].symbol = NULL;
				PAPIERROR("Expected PFM event after DERIVED token at line %d of %s -- ignoring", line_no, name);
				continue;
			}

			if (i == PAPI_EVENTS_IN_DERIVED_EVENT) {
				t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
			}

			// if something was provided following the list of events to be used by the operation, process it
			if ( t!= NULL  && strlen(t) > 0 ) {
				do {
					// save the field name
					char *fptr = papi_strdup(t);

					// get the value to be used with this field
					t = trim_note(strtok_r(NULL, ",", &tok_save_ptr));
					if ( t== NULL  || strlen(t) == 0 ) {
						papi_free(fptr);
						break;
					}

					// Handle optional short descriptions, long descriptions and notes
					if (strcasecmp(fptr, "SDESC") == 0) {
						results[res_idx].short_descr = papi_strdup(t);
					}
					if (strcasecmp(fptr, "LDESC") == 0) {
						results[res_idx].long_descr = papi_strdup(t);
					}
					if (strcasecmp(fptr, "NOTE") == 0) {
						results[res_idx].note = papi_strdup(t);
					}

					SUBDBG( "Found %s (%s) on line %d\n", fptr, t, line_no);
					papi_free (fptr);

					// look for another field name
					t = trim_string(strtok_r(NULL, ",", &tok_save_ptr));
					if ( t== NULL  || strlen(t) == 0 ) {
						break;
					}
				} while (t != NULL);
			}
			(*event_count)++;
			continue;
		}

		PAPIERROR("Unrecognized token %s at line %d of %s -- ignoring", t, line_no, name);
	}

	if (event_file) {
		fclose(event_file);
	}

	SUBDBG("EXIT: Done processing derived event file.\n");
	return PAPI_OK;
}