Exemplo n.º 1
0
int
_papi_hwd_read( hwd_context_t * ctx, hwd_control_state_t * spc, long long **dp,
				int flags )
{
	if ( flags & PAPI_PAUSED ) {
		vperfctr_read_state( ctx->perfctr, &spc->state, NULL );
	} else {
		SUBDBG( "vperfctr_read_ctrs\n" );
		if ( spc->rvperfctr != NULL ) {
			rvperfctr_read_ctrs( spc->rvperfctr, &spc->state );
		} else {
			vperfctr_read_ctrs( ctx->perfctr, &spc->state );
		}
	}

	*dp = ( long long * ) spc->state.pmc;
#ifdef DEBUG
	{
		if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
			int i;
			for ( i = 0;
				  i <
				  spc->control.cpu_control.nractrs +
				  spc->control.cpu_control.nrictrs; i++ ) {
				SUBDBG( "raw val hardware index %d is %lld\n", i,
						( long long ) spc->state.pmc[i] );
			}
		}
	}
#endif
	return ( PAPI_OK );
}
Exemplo n.º 2
0
int
_papi_hwd_read( hwd_context_t * ctx, hwd_control_state_t * spc, long long **dp,
				int flags )
{
	pmc_read_state( _papi_hwi_system_info.num_cntrs, &spc->state );
	*dp = ( long long * ) spc->state.sum.pmc;
#ifdef DEBUG
	{
		if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
			unsigned int i;
			for ( i = 0; i < spc->control.cpu_control.nractrs; i++ ) {
				SUBDBG( "raw val hardware index %d is %lld\n", i,
						( long long ) spc->state.sum.pmc[i] );
			}
		}
	}
#endif
	return ( PAPI_OK );
}
Exemplo n.º 3
0
static int
build_tables( void )
{
	int i;
	int regno;
	int npic;
	einfo_t *ep;
	int n;
	int npresets;
	npic = cpc_getnpic( cpuver );
	nctrs = 0;
	for ( regno = 0; regno < npic; ++regno ) {
		cpc_walk_names( cpuver, regno, 0, action );
	}
	SUBDBG( "%d counters\n", nctrs );
	if ( ( ctrs = papi_malloc( nctrs * sizeof ( struct ctr_info ) ) ) == 0 ) {
		return PAPI_ENOMEM;
	}
	nctrs = 0;
	for ( regno = 0; regno < npic; ++regno ) {
		cpc_walk_names( cpuver, regno, ( void * ) 1, action );
	}
	SUBDBG( "%d counters\n", nctrs );
#if DEBUG
	if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
		for ( i = 0; i < nctrs; ++i ) {
			SUBDBG( "%s: bits (%x,%x) pics %x\n", ctrs[i].name, ctrs[i].bits[0],
					ctrs[i].bits[1], ctrs[i].bitmask );
		}
	}
#endif
	/* Build the native event table */
	if ( ( native_table =
		   papi_malloc( nctrs * sizeof ( native_info_t ) ) ) == 0 ) {
		papi_free( ctrs );
		return PAPI_ENOMEM;
	}
	for ( i = 0; i < nctrs; ++i ) {
		native_table[i].name[39] = 0;
		strncpy( native_table[i].name, ctrs[i].name, 39 );
		if ( ctrs[i].bitmask & 1 )
			native_table[i].encoding[0] = ctrs[i].bits[0];
		else
			native_table[i].encoding[0] = -1;
		if ( ctrs[i].bitmask & 2 )
			native_table[i].encoding[1] = ctrs[i].bits[1];
		else
			native_table[i].encoding[1] = -1;
	}
	papi_free( ctrs );

	/* Build the preset table */
	if ( cpuver <= CPC_ULTRA2 ) {
		n = sizeof ( us2info ) / sizeof ( einfo_t );
		ep = us2info;
	} else if ( cpuver <= LASTULTRA3 ) {
		n = sizeof ( us3info ) / sizeof ( einfo_t );
		ep = us3info;
	} else
		return PAPI_ESBSTR;
	preset_table = papi_malloc( ( n + 1 ) * sizeof ( hwi_search_t ) );
	npresets = 0;
	for ( i = 0; i < n; ++i ) {
		add_preset( preset_table, &npresets, ep[i] );
	}
	memset( &preset_table[npresets], 0, sizeof ( hwi_search_t ) );

#ifdef DEBUG
	if ( ISLEVEL( DEBUG_SUBSTRATE ) ) {
		SUBDBG( "Native table: %d\n", nctrs );
		for ( i = 0; i < nctrs; ++i ) {
			SUBDBG( "%40s: %8x %8x\n", native_table[i].name,
					native_table[i].encoding[0], native_table[i].encoding[1] );
		}
		SUBDBG( "\nPreset table: %d\n", npresets );
		for ( i = 0; preset_table[i].event_code != 0; ++i ) {
			SUBDBG( "%8x: op %2d e0 %8x e1 %8x\n",
					preset_table[i].event_code,
					preset_table[i].data.derived,
					preset_table[i].data.native[0],
					preset_table[i].data.native[1] );
		}
	}
#endif

	_solaris_vector.cmp_info.num_native_events = nctrs;

	return PAPI_OK;
}
Exemplo n.º 4
0
static int
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_ESBSTR );
	SUBDBG( "CPC version %d successfully opened\n", CPC_VER_CURRENT );

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

	/* Global variable cpuver */

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

#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_ESBSTR );

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

	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 );

	/* Number of PMCs */

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

	_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 );
}
Exemplo n.º 5
0
int
MPX_start( MPX_EventSet * mpx_events )
{
	int retval = PAPI_OK;
	int i;
	long long values[2];
	long long cycles_this_slice, current_thread_mpx_c = 0;
	Threadlist *t;

	t = mpx_events->mythr;

	mpx_hold(  );

	if ( t->cur_event && t->cur_event->active ) {
		current_thread_mpx_c += t->total_c;
		retval = PAPI_read( t->cur_event->papi_event, values );
		assert( retval == PAPI_OK );
		if ( retval == PAPI_OK ) {
			cycles_this_slice = ( t->cur_event->pi.event_type == SCALE_EVENT )
				? values[0] : values[1];
		} else {
			values[0] = values[1] = 0;
			cycles_this_slice = 0;
		}

	} else {
		values[0] = values[1] = 0;
		cycles_this_slice = 0;
	}

	/* Make all events in this set active, and for those
	 * already active, get the current count and cycles.
	 */
	for ( i = 0; i < mpx_events->num_events; i++ ) {
		MasterEvent *mev = mpx_events->mev[i];

		if ( mev->active++ ) {
			mpx_events->start_values[i] = mev->count_estimate;
			mpx_events->start_hc[i] = mev->cycles;

			/* If this happens to be the currently-running
			 * event, add in the current amounts from this
			 * time slice.  If it's a rate, though, don't
			 * bother since the event might not have been
			 * running long enough to get an accurate count.
			 */
			if ( t->cur_event && !( t->cur_event->is_a_rate ) ) {
#ifdef MPX_NONDECR_HYBRID
				if ( mev != t->cur_event ) {	/* This event is not running this slice */
					mpx_events->start_values[i] +=
						( long long ) ( mev->rate_estimate *
										( cycles_this_slice + t->total_c -
										  mev->prev_total_c ) );
				} else {	 /* The event is running, use current value + estimate */
					if ( cycles_this_slice >= MPX_MINCYC )
						mpx_events->start_values[i] += values[0] + ( long long )
							( ( values[0] / ( double ) cycles_this_slice ) *
							  ( t->total_c - mev->prev_total_c ) );
					else	 /* Use previous rate if the event has run too short time */
						mpx_events->start_values[i] += values[0] + ( long long )
							( mev->rate_estimate *
							  ( t->total_c - mev->prev_total_c ) );
				}
#endif
			} else {
				mpx_events->start_values[i] = mev->count;
			}
		} else {
			/* The = 0 isn't actually necessary; we only need
			 * to sync up the mpx event to the master event,
			 * but it seems safe to set the mev to 0 here, and
			 * that gives us a change to avoid (very unlikely)
			 * rollover problems for events used repeatedly over
			 * a long time.
			 */
			mpx_events->start_values[i] = 0;
			mpx_events->stop_values[i] = 0;
			mpx_events->start_hc[i] = mev->cycles = 0;
			mev->count_estimate = 0;
			mev->rate_estimate = 0.0;
			mev->prev_total_c = current_thread_mpx_c;
			mev->count = 0;
		}
		/* Adjust start value to include events and cycles
		 * counted previously for this event set.
		 */
	}

	mpx_events->status = MPX_RUNNING;

	/* Start first counter if one isn't already running */
	if ( t->cur_event == NULL ) {
		/* Pick an events at random to start. */
		int index = ( rand_r( &randomseed ) % mpx_events->num_events );
		t->cur_event = mpx_events->mev[index];
		t->total_c = 0;
		t->cur_event->prev_total_c = 0;
		mpx_events->start_c = 0;
		retval = PAPI_start( mpx_events->mev[index]->papi_event );
		assert( retval == PAPI_OK );
	} else {
		/* If an event is already running, record the starting cycle
		 * count for mpx_events, which is the accumlated cycle count
		 * for the master event set plus the cycles for this time
		 * slice.
		 */
		mpx_events->start_c = t->total_c + cycles_this_slice;
	}

#if defined(DEBUG)
	if ( ISLEVEL( DEBUG_MULTIPLEX ) ) {
		MPXDBG( "%s:%d:: start_c=%lld  thread->total_c=%lld\n", __FILE__,
				__LINE__, mpx_events->start_c, t->total_c );
		for ( i = 0; i < mpx_events->num_events; i++ ) {
			MPXDBG
				( "%s:%d:: start_values[%d]=%lld  estimate=%lld rate=%g last active=%lld\n",
				  __FILE__, __LINE__, i, mpx_events->start_values[i],
				  mpx_events->mev[i]->count_estimate,
				  mpx_events->mev[i]->rate_estimate,
				  mpx_events->mev[i]->prev_total_c );
		}
	}
#endif

	mpx_release(  );

	retval = mpx_startup_itimer(  );

	return retval;
}
Exemplo n.º 6
0
int
_papi_hwi_shutdown_global_threads( void )
{
        int err,num_threads,i;
	ThreadInfo_t *tmp,*next;
	unsigned long our_tid;

	tmp = _papi_hwi_lookup_thread( 0 );

	if ( tmp == NULL ) {
	   THRDBG( "Did not find my thread for shutdown!\n" );
	   err = PAPI_EBUG;
	}
	else {
	   our_tid=tmp->tid;

	   THRDBG("Shutting down %ld\n",our_tid);

	   err = _papi_hwi_shutdown_thread( tmp );


	   /* count threads */
	   tmp = ( ThreadInfo_t * ) _papi_hwi_thread_head;
	   num_threads=0;
	   while(tmp!=NULL) {
	      num_threads++;
	      if (tmp->next==_papi_hwi_thread_head) break;
	      tmp=tmp->next;
	   }

	   /* Shut down all threads allocated by this thread */
	   /* Urgh it's a circular list where we removed in the loop  */
	   /* so the only sane way to do it is get a count in advance */
	   tmp = ( ThreadInfo_t * ) _papi_hwi_thread_head;

	   for(i=0;i<num_threads;i++) {

	      next=tmp->next;

	      THRDBG("looking at #%d %ld our_tid: %ld alloc_tid: %ld\n",
		     i,tmp->tid,our_tid,tmp->allocator_tid);
	    
	      if (tmp->allocator_tid==our_tid) {
		 THRDBG("Also removing thread %ld\n",tmp->tid);
	         err = _papi_hwi_shutdown_thread( tmp );
	      }
  
	      tmp=next;

	   }
	}


#ifdef DEBUG
	if ( ISLEVEL( DEBUG_THREADS ) ) {
		if ( _papi_hwi_thread_head ) {
			THRDBG( "Thread head %p still exists!\n", _papi_hwi_thread_head );
		}
	}
#endif

#if defined(HAVE_THREAD_LOCAL_STORAGE)
	_papi_hwi_my_thread = NULL;
#endif
	_papi_hwi_thread_head = NULL;
	_papi_hwi_thread_id_fn = NULL;
#if defined(ANY_THREAD_GETS_SIGNAL)
	_papi_hwi_thread_kill_fn = NULL;
#endif

	return err;
}