|
PAPI
5.1.0.2
|
| int PAPI_accum | ( | int | EventSet, |
| long long * | values | ||
| ) |
accumulate and reset hardware events from an event set
Definition at line 2671 of file papi.c.
{
EventSetInfo_t *ESI;
hwd_context_t *context;
int i, cidx, retval;
long long a, b, c;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( values == NULL )
papi_return( PAPI_EINVAL );
if ( ESI->state & PAPI_RUNNING ) {
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
retval = MPX_read( ESI->multiplex.mpx_evset, ESI->sw_stop, 0 );
} else {
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, NULL );
retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
}
if ( retval != PAPI_OK )
papi_return( retval );
}
for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
a = ESI->sw_stop[i];
b = values[i];
c = a + b;
values[i] = c;
}
papi_return( PAPI_reset( EventSet ) );
}
| int PAPI_add_event | ( | int | EventSet, |
| int | Event | ||
| ) |
add single PAPI preset or native hardware event to an event set
Definition at line 1612 of file papi.c.
{
APIDBG("Entry: EventSet: %d, EventCode: 0x%x\n", EventSet, EventCode);
EventSetInfo_t *ESI;
/* Is the EventSet already in existence? */
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/* Check argument for validity */
if ( ( ( EventCode & PAPI_PRESET_MASK ) == 0 ) &&
( EventCode & PAPI_NATIVE_MASK ) == 0 )
papi_return( PAPI_EINVAL );
/* Of course, it must be stopped in order to modify it. */
if ( ESI->state & PAPI_RUNNING )
papi_return( PAPI_EISRUN );
/* Now do the magic. */
papi_return( _papi_hwi_add_event( ESI, EventCode ) );
}
| int PAPI_add_events | ( | int | EventSet, |
| int * | Events, | ||
| int | number | ||
| ) |
add array of PAPI preset or native hardware events to an event set
Definition at line 5736 of file papi.c.
{
int i, retval;
if ( ( Events == NULL ) || ( number <= 0 ) )
papi_return( PAPI_EINVAL );
for ( i = 0; i < number; i++ ) {
retval = PAPI_add_event( EventSet, Events[i] );
if ( retval != PAPI_OK ) {
if ( i == 0 )
papi_return( retval );
else
return ( i );
}
}
return ( PAPI_OK );
}
| int PAPI_add_named_event | ( | int | EventSet, |
| char * | EventName | ||
| ) |
add an event by name to a PAPI event set
Definition at line 1824 of file papi.c.
{
int ret, code;
ret = PAPI_event_name_to_code( EventName, &code );
if ( ret == PAPI_OK ) ret = PAPI_add_event( EventSet, code );
papi_return( ret );
}
| int PAPI_assign_eventset_component | ( | int | EventSet, |
| int | cidx | ||
| ) |
assign a component index to an existing but empty eventset
Definition at line 1475 of file papi.c.
{
EventSetInfo_t *ESI;
int retval;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/* validate cidx */
retval = valid_component( cidx );
if ( retval < 0 )
papi_return( retval );
/* cowardly refuse to reassign eventsets */
if ( ESI->CmpIdx >= 0 )
return PAPI_EINVAL;
return ( _papi_hwi_assign_eventset( ESI, cidx ) );
}
| int PAPI_attach | ( | int | EventSet, |
| unsigned long | tid | ||
| ) |
attach specified event set to a specific process or thread id
Definition at line 3123 of file papi.c.
{
return ( _papi_set_attach( PAPI_ATTACH, EventSet, tid ) );
}
| int PAPI_cleanup_eventset | ( | int | EventSet | ) |
remove all PAPI events from an event set
Definition at line 2813 of file papi.c.
{
EventSetInfo_t *ESI;
int i, cidx, total, retval;
APIDBG("Attempting to cleanup Eventset %d\n",EventSet);
/* Is the EventSet already in existence? */
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/* if the eventset has no index and no events, return OK
otherwise return NOCMP */
cidx = valid_ESI_component( ESI );
if ( cidx < 0 ) {
if ( ESI->NumberOfEvents )
papi_return( cidx );
papi_return( PAPI_OK );
}
/* Of course, it must be stopped in order to modify it. */
if ( ESI->state & PAPI_RUNNING )
papi_return( PAPI_EISRUN );
/* clear overflow flag and turn off hardware overflow handler */
if ( ESI->state & PAPI_OVERFLOWING ) {
total = ESI->overflow.event_counter;
for ( i = 0; i < total; i++ ) {
retval = PAPI_overflow( EventSet,
ESI->overflow.EventCode[0], 0, 0, NULL );
if ( retval != PAPI_OK )
papi_return( retval );
}
}
/* clear profile flag and turn off hardware profile handler */
if ( ( ESI->state & PAPI_PROFILING ) &&
_papi_hwd[cidx]->cmp_info.hardware_intr &&
!( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
total = ESI->profile.event_counter;
for ( i = 0; i < total; i++ ) {
retval =
PAPI_sprofil( NULL, 0, EventSet, ESI->profile.EventCode[0], 0,
PAPI_PROFIL_POSIX );
if ( retval != PAPI_OK )
papi_return( retval );
}
}
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
retval = MPX_cleanup( &ESI->multiplex.mpx_evset );
if ( retval != PAPI_OK )
papi_return( retval );
}
retval = _papi_hwd[cidx]->cleanup_eventset( ESI->ctl_state );
if ( retval != PAPI_OK )
papi_return( retval );
/* Now do the magic */
papi_return( _papi_hwi_cleanup_eventset( ESI ) );
}
| int PAPI_create_eventset | ( | int * | EventSet | ) |
create a new empty PAPI event set
Definition at line 1411 of file papi.c.
{
APIDBG("Entry: EventSet: %p\n", EventSet);
ThreadInfo_t *master;
int retval;
if ( init_level == PAPI_NOT_INITED )
papi_return( PAPI_ENOINIT );
retval = _papi_hwi_lookup_or_create_thread( &master, 0 );
if ( retval )
papi_return( retval );
papi_return( _papi_hwi_create_eventset( EventSet, master ) );
}
| int PAPI_destroy_eventset | ( | int * | EventSet | ) |
deallocates memory associated with an empty PAPI event set
Definition at line 1952 of file papi.c.
{
EventSetInfo_t *ESI;
APIDBG("Destroying Eventset %d\n",*EventSet);
/* check for pre-existing ESI */
if ( EventSet == NULL )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( *EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
if ( !( ESI->state & PAPI_STOPPED ) )
papi_return( PAPI_EISRUN );
if ( ESI->NumberOfEvents )
papi_return( PAPI_EINVAL );
_papi_hwi_remove_EventSet( ESI );
*EventSet = PAPI_NULL;
return PAPI_OK;
}
| int PAPI_detach | ( | int | EventSet | ) |
detach specified event set from a previously specified process or thread id
Definition at line 3182 of file papi.c.
{
return ( _papi_set_attach( PAPI_DETACH, EventSet, 0 ) );
}
| int PAPI_disable_component | ( | int | cidx | ) |
Disables a component before init
Definition at line 6542 of file papi.c.
{
const PAPI_component_info_t *cinfo;
/* Can only run before PAPI_library_init() is called */
if (init_level != PAPI_NOT_INITED) {
return PAPI_ENOINIT;
}
cinfo=PAPI_get_component_info(cidx);
if (cinfo==NULL) return PAPI_ENOCMP;
((PAPI_component_info_t *)cinfo)->disabled=1;
strcpy(((PAPI_component_info_t *)cinfo)->disabled_reason,
"Disabled by PAPI_disable_component()");
return PAPI_OK;
}
| int PAPI_disable_component_by_name | ( | char * | name | ) |
Disable, before library init, a component by name.
Definition at line 6592 of file papi.c.
{
int cidx;
/* I can only be called before init time */
if (init_level!=PAPI_NOT_INITED) {
return PAPI_ENOINIT;
}
cidx = PAPI_get_component_index(name);
if (cidx>=0) {
return PAPI_disable_component(cidx);
}
return PAPI_ENOCMP;
}
| int PAPI_enum_cmp_event | ( | int * | EventCode, |
| int | modifier, | ||
| int | cidx | ||
| ) |
return the event code for the next available component event
Definition at line 1321 of file papi.c.
{
int i = *EventCode;
int retval;
int event_code;
if ( _papi_hwi_invalid_cmp(cidx) || ( (IS_PRESET(i)) && cidx > 0 ) ) {
return PAPI_ENOCMP;
}
if ( IS_PRESET(i) ) {
if ( modifier == PAPI_ENUM_FIRST ) {
*EventCode = ( int ) PAPI_PRESET_MASK;
return PAPI_OK;
}
i &= PAPI_PRESET_AND_MASK;
while ( ++i < PAPI_MAX_PRESET_EVENTS ) {
if ( _papi_hwi_presets[i].symbol == NULL )
return ( PAPI_ENOEVNT ); /* NULL pointer terminates list */
if ( modifier & PAPI_PRESET_ENUM_AVAIL ) {
if ( _papi_hwi_presets[i].count == 0 )
continue;
}
*EventCode = ( int ) ( i | PAPI_PRESET_MASK );
return PAPI_OK;
}
} else if ( IS_NATIVE(i) ) {
// if (!_papi_hwd[cidx]->cmp_info.disabled) {
// return PAPI_ENOEVNT
// }
/* Should we check against num native events here? */
event_code=_papi_hwi_eventcode_to_native(*EventCode);
retval = _papi_hwd[cidx]->ntv_enum_events((unsigned int *)&event_code, modifier );
/* re-apply Component ID to the returned Event */
*EventCode = _papi_hwi_native_to_eventcode(cidx,event_code);
return retval;
}
papi_return( PAPI_EINVAL );
}
| int PAPI_enum_event | ( | int * | EventCode, |
| int | modifier | ||
| ) |
return the event code for the next available preset or natvie event
Definition at line 1156 of file papi.c.
{
int i = *EventCode;
int retval;
int cidx;
int event_code;
cidx = _papi_hwi_component_index( *EventCode );
if (cidx < 0) return PAPI_ENOCMP;
/* Do we handle presets in componets other than CPU? */
/* if (( IS_PRESET(i) ) && cidx > 0 )) return PAPI_ENOCMP; */
if ( IS_PRESET(i) ) {
if ( modifier == PAPI_ENUM_FIRST ) {
*EventCode = ( int ) PAPI_PRESET_MASK;
return ( PAPI_OK );
}
i &= PAPI_PRESET_AND_MASK;
while ( ++i < PAPI_MAX_PRESET_EVENTS ) {
if ( _papi_hwi_presets[i].symbol == NULL )
return ( PAPI_ENOEVNT ); /* NULL pointer terminates list */
if ( modifier & PAPI_PRESET_ENUM_AVAIL ) {
if ( _papi_hwi_presets[i].count == 0 )
continue;
}
*EventCode = ( int ) ( i | PAPI_PRESET_MASK );
return ( PAPI_OK );
}
} else if ( IS_NATIVE(i) ) {
/* Should check against num native events here */
event_code=_papi_hwi_eventcode_to_native((int)*EventCode);
retval = _papi_hwd[cidx]->ntv_enum_events((unsigned int *)&event_code, modifier );
/* re-apply Component ID to the returned Event */
*EventCode = _papi_hwi_native_to_eventcode(cidx,event_code);
return retval;
} else if ( IS_USER_DEFINED(i) ) {
if ( modifier == PAPI_ENUM_FIRST ) {
*EventCode = (int) 0x0;
return ( PAPI_OK );
}
i &= PAPI_UE_AND_MASK;
++i;
if ( (int)_papi_user_events_count <= i )
*EventCode = i;
return ( PAPI_OK );
}
papi_return( PAPI_EINVAL );
}
| int PAPI_event_code_to_name | ( | int | EventCode, |
| char * | out | ||
| ) |
translate an integer PAPI event code into an ASCII PAPI preset or native name
Definition at line 926 of file papi.c.
{
if ( out == NULL )
papi_return( PAPI_EINVAL );
if ( IS_PRESET(EventCode) ) {
EventCode &= PAPI_PRESET_AND_MASK;
if ( ( EventCode >= PAPI_MAX_PRESET_EVENTS )
|| ( _papi_hwi_presets[EventCode].symbol == NULL ) )
papi_return( PAPI_ENOTPRESET );
strncpy( out, _papi_hwi_presets[EventCode].symbol,
PAPI_MAX_STR_LEN );
papi_return( PAPI_OK );
}
if ( IS_NATIVE(EventCode) ) {
return ( _papi_hwi_native_code_to_name
( ( unsigned int ) EventCode, out, PAPI_MAX_STR_LEN ) );
}
if ( IS_USER_DEFINED(EventCode) ) {
EventCode &= PAPI_UE_AND_MASK;
if ( EventCode < 0 || EventCode > (int)_papi_user_events_count )
papi_return( PAPI_EINVAL );
strncpy( out, _papi_user_events[EventCode].symbol,
PAPI_MIN_STR_LEN);
papi_return( PAPI_OK );
}
papi_return( PAPI_ENOEVNT );
}
| int PAPI_event_name_to_code | ( | char * | in, |
| int * | out | ||
| ) |
translate an ASCII PAPI preset or native name into an integer PAPI event code
Definition at line 1013 of file papi.c.
{
APIDBG("Entry: in: %p, name: %s, out: %p\n", in, in, out);
int i;
if ( ( in == NULL ) || ( out == NULL ) )
papi_return( PAPI_EINVAL );
if ( init_level == PAPI_NOT_INITED )
papi_return( PAPI_ENOINIT );
/* All presets start with "PAPI_" so no need to */
/* do an exhaustive search if that's not there */
if (strncmp(in, "PAPI_", 5) == 0) {
for(i = 0; i < PAPI_MAX_PRESET_EVENTS; i++ ) {
if ( ( _papi_hwi_presets[i].symbol )
&& ( strcasecmp( _papi_hwi_presets[i].symbol, in ) == 0) ) {
*out = ( int ) ( i | PAPI_PRESET_MASK );
papi_return( PAPI_OK );
}
}
}
for ( i=0; i < (int)_papi_user_events_count; i++ ) {
if ( strcasecmp( _papi_user_events[i].symbol, in ) == 0 ) {
*out = (int) ( i | PAPI_UE_MASK );
papi_return( PAPI_OK );
}
}
papi_return( _papi_hwi_native_name_to_code( in, out ) );
}
| int PAPI_get_cmp_opt | ( | int | option, |
| PAPI_option_t * | ptr, | ||
| int | cidx | ||
| ) |
query the component specific option settings of a specific event set
Definition at line 4247 of file papi.c.
{
if (_papi_hwi_invalid_cmp(cidx)) {
return PAPI_ECMP;
}
switch ( option ) {
/* For now, MAX_HWCTRS and MAX CTRS are identical.
At some future point, they may map onto different values.
*/
case PAPI_MAX_HWCTRS:
return ( _papi_hwd[cidx]->cmp_info.num_cntrs );
case PAPI_MAX_MPX_CTRS:
return ( _papi_hwd[cidx]->cmp_info.num_mpx_cntrs );
case PAPI_DEFDOM:
return ( _papi_hwd[cidx]->cmp_info.default_domain );
case PAPI_DEFGRN:
return ( _papi_hwd[cidx]->cmp_info.default_granularity );
case PAPI_SHLIBINFO:
{
int retval;
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
retval = _papi_os_vector.update_shlib_info( &_papi_hwi_system_info );
ptr->shlib_info = &_papi_hwi_system_info.shlib_info;
papi_return( retval );
}
case PAPI_COMPONENTINFO:
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ptr->cmp_info = &( _papi_hwd[cidx]->cmp_info );
return PAPI_OK;
default:
papi_return( PAPI_EINVAL );
}
return PAPI_OK;
}
| int PAPI_get_component_index | ( | char * | name | ) |
Return component index for component with matching name
Definition at line 6486 of file papi.c.
{
int cidx;
const PAPI_component_info_t *cinfo;
for(cidx=0;cidx<papi_num_components;cidx++) {
cinfo=PAPI_get_component_info(cidx);
if (cinfo==NULL) return PAPI_ENOCMP;
if (!strncmp(name,cinfo->name,strlen(cinfo->name))) {
return cidx;
}
}
return PAPI_ENOCMP;
}
| const PAPI_component_info_t* PAPI_get_component_info | ( | int | cidx | ) |
| int PAPI_get_dmem_info | ( | PAPI_dmem_info_t * | dest | ) |
get dynamic memory usage information
Definition at line 5936 of file papi.c.
{
if ( dest == NULL )
return PAPI_EINVAL;
memset( ( void * ) dest, 0x0, sizeof ( PAPI_dmem_info_t ) );
return ( _papi_os_vector.get_dmem_info( dest ) );
}
| int PAPI_get_event_component | ( | int | EventCode | ) |
return which component an EventCode belongs to
Definition at line 6460 of file papi.c.
{
return _papi_hwi_component_index( EventCode);
}
| int PAPI_get_event_info | ( | int | EventCode, |
| PAPI_event_info_t * | info | ||
| ) |
get the name and descriptions for a given preset or native event code
Definition at line 848 of file papi.c.
{
int i;
if ( info == NULL )
papi_return( PAPI_EINVAL );
if ( IS_PRESET(EventCode) ) {
i = EventCode & PAPI_PRESET_AND_MASK;
if ( i >= PAPI_MAX_PRESET_EVENTS )
papi_return( PAPI_ENOTPRESET );
papi_return( _papi_hwi_get_preset_event_info( EventCode, info ) );
}
if ( IS_NATIVE(EventCode) ) {
papi_return( _papi_hwi_get_native_event_info
( ( unsigned int ) EventCode, info ) );
}
if ( IS_USER_DEFINED(EventCode) ) {
papi_return( PAPI_OK );
}
papi_return( PAPI_ENOTPRESET );
}
| int PAPI_get_eventset_component | ( | int | EventSet | ) |
return which component an EventSet is assigned to
Definition at line 1518 of file papi.c.
{
EventSetInfo_t *ESI;
int retval;
/* validate eventset */
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/* check if a component has been assigned */
if ( ESI->CmpIdx < 0 )
papi_return( PAPI_ENOCMP );
/* validate CmpIdx */
retval = valid_component( ESI->CmpIdx );
if ( retval < 0 )
papi_return( retval );
/* return the index */
return ( ESI->CmpIdx );
}
| const PAPI_exe_info_t* PAPI_get_executable_info | ( | void | ) |
get the executable's address space information
Definition at line 5990 of file papi.c.
{
PAPI_option_t ptr;
int retval;
memset( &ptr, 0, sizeof ( ptr ) );
retval = PAPI_get_opt( PAPI_EXEINFO, &ptr );
if ( retval == PAPI_OK )
return ( ptr.exe_info );
else
return ( NULL );
}
| const PAPI_hw_info_t* PAPI_get_hardware_info | ( | void | ) |
get information about the system hardware
Definition at line 6061 of file papi.c.
{
PAPI_option_t ptr;
int retval;
memset( &ptr, 0, sizeof ( ptr ) );
retval = PAPI_get_opt( PAPI_HWINFO, &ptr );
if ( retval == PAPI_OK )
return ( ptr.hw_info );
else
return ( NULL );
}
| int PAPI_get_multiplex | ( | int | EventSet | ) |
get the multiplexing status of specified event set
Definition at line 3942 of file papi.c.
{
PAPI_option_t popt;
int retval;
popt.multiplex.eventset = EventSet;
retval = PAPI_get_opt( PAPI_MULTIPLEX, &popt );
if ( retval < 0 )
retval = 0;
return retval;
}
| int PAPI_get_opt | ( | int | option, |
| PAPI_option_t * | ptr | ||
| ) |
query the option settings of the PAPI library or a specific event set
Definition at line 4056 of file papi.c.
{
EventSetInfo_t *ESI;
if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
papi_return( PAPI_ENOINIT );
switch ( option ) {
case PAPI_DETACH:
{
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
ptr->attach.tid = ESI->attach.tid;
return ( ( ESI->state & PAPI_ATTACHED ) == 0 );
}
case PAPI_ATTACH:
{
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
ptr->attach.tid = ESI->attach.tid;
return ( ( ESI->state & PAPI_ATTACHED ) != 0 );
}
case PAPI_CPU_ATTACH:
{
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
ptr->cpu.cpu_num = ESI->CpuInfo->cpu_num;
return ( ( ESI->state & PAPI_CPU_ATTACHED ) != 0 );
}
case PAPI_DEF_MPX_NS:
{
/* xxxx for now, assume we only check against cpu component */
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ptr->multiplex.ns = _papi_os_info.itimer_ns;
return ( PAPI_OK );
}
case PAPI_DEF_ITIMER_NS:
{
/* xxxx for now, assume we only check against cpu component */
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ptr->itimer.ns = _papi_os_info.itimer_ns;
return ( PAPI_OK );
}
case PAPI_DEF_ITIMER:
{
/* xxxx for now, assume we only check against cpu component */
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ptr->itimer.itimer_num = _papi_os_info.itimer_num;
ptr->itimer.itimer_sig = _papi_os_info.itimer_sig;
ptr->itimer.ns = _papi_os_info.itimer_ns;
ptr->itimer.flags = 0;
return ( PAPI_OK );
}
case PAPI_MULTIPLEX:
{
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( ptr->multiplex.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
ptr->multiplex.ns = ESI->multiplex.ns;
ptr->multiplex.flags = ESI->multiplex.flags;
return ( ESI->state & PAPI_MULTIPLEXING ) != 0;
}
case PAPI_PRELOAD:
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
memcpy( &ptr->preload, &_papi_hwi_system_info.preload_info,
sizeof ( PAPI_preload_info_t ) );
break;
case PAPI_DEBUG:
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ptr->debug.level = _papi_hwi_error_level;
ptr->debug.handler = _papi_hwi_debug_handler;
break;
case PAPI_CLOCKRATE:
return ( ( int ) _papi_hwi_system_info.hw_info.cpu_max_mhz );
case PAPI_MAX_CPUS:
return ( _papi_hwi_system_info.hw_info.ncpu );
/* For now, MAX_HWCTRS and MAX CTRS are identical.
At some future point, they may map onto different values.
*/
case PAPI_INHERIT:
{
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( ptr->inherit.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
ptr->inherit.inherit = ESI->inherit.inherit;
return ( PAPI_OK );
}
case PAPI_GRANUL:
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( ptr->granularity.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
ptr->granularity.granularity = ESI->granularity.granularity;
break;
case PAPI_EXEINFO:
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ptr->exe_info = &_papi_hwi_system_info.exe_info;
break;
case PAPI_HWINFO:
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ptr->hw_info = &_papi_hwi_system_info.hw_info;
break;
case PAPI_DOMAIN:
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( ptr->domain.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
ptr->domain.domain = ESI->domain.domain;
return ( PAPI_OK );
case PAPI_LIB_VERSION:
return ( PAPI_VERSION );
/* The following cases all require a component index
and are handled by PAPI_get_cmp_opt() with cidx == 0*/
case PAPI_MAX_HWCTRS:
case PAPI_MAX_MPX_CTRS:
case PAPI_DEFDOM:
case PAPI_DEFGRN:
case PAPI_SHLIBINFO:
case PAPI_COMPONENTINFO:
return ( PAPI_get_cmp_opt( option, ptr, 0 ) );
default:
papi_return( PAPI_EINVAL );
}
return ( PAPI_OK );
}
| int PAPI_get_overflow_event_index | ( | int | Eventset, |
| long long | overflow_vector, | ||
| int * | array, | ||
| int * | number | ||
| ) |
# decomposes an overflow_vector into an event index array
Definition at line 6395 of file papi.c.
{
EventSetInfo_t *ESI;
int set_bit, j, pos;
int count = 0, k;
if ( overflow_vector == ( long long ) 0 )
papi_return( PAPI_EINVAL );
if ( ( array == NULL ) || ( number == NULL ) )
papi_return( PAPI_EINVAL );
if ( *number < 1 )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/* in case the eventset is empty */
if ( ESI->NumberOfEvents == 0 )
papi_return( PAPI_EINVAL );
while ( ( set_bit = ffsll( overflow_vector ) ) ) {
set_bit -= 1;
overflow_vector ^= ( long long ) 1 << set_bit;
for ( j = 0; j < ESI->NumberOfEvents; j++ ) {
for ( k = 0, pos = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT && pos >= 0; k++ ) {
pos = ESI->EventInfoArray[j].pos[k];
if ( ( set_bit == pos ) &&
( ( ESI->EventInfoArray[j].derived == NOT_DERIVED ) ||
( ESI->EventInfoArray[j].derived == DERIVED_CMPD ) ) ) {
array[count++] = j;
if ( count == *number )
return PAPI_OK;
break;
}
}
}
}
*number = count;
return PAPI_OK;
}
| long long PAPI_get_real_cyc | ( | void | ) |
return the total number of cycles since some arbitrary starting point
Definition at line 6093 of file papi.c.
{
return ( _papi_os_vector.get_real_cycles( ) );
}
| long long PAPI_get_real_nsec | ( | void | ) |
return the total number of nanoseconds since some arbitrary starting point
Definition at line 6113 of file papi.c.
{
return ( ( _papi_os_vector.get_real_nsec( )));
}
| long long PAPI_get_real_usec | ( | void | ) |
return the total number of microseconds since some arbitrary starting point
Definition at line 6140 of file papi.c.
{
return ( _papi_os_vector.get_real_usec( ) );
}
| const PAPI_shlib_info_t* PAPI_get_shared_lib_info | ( | void | ) |
get information about the shared libraries used by the process
Definition at line 6020 of file papi.c.
{
PAPI_option_t ptr;
int retval;
memset( &ptr, 0, sizeof ( ptr ) );
retval = PAPI_get_opt( PAPI_SHLIBINFO, &ptr );
if ( retval == PAPI_OK )
return ( ptr.shlib_info );
else
return ( NULL );
}
| int PAPI_get_thr_specific | ( | int | tag, |
| void ** | ptr | ||
| ) |
return a pointer to a thread specific stored data structure
Definition at line 360 of file papi.c.
{
ThreadInfo_t *thread;
int doall = 0, retval = PAPI_OK;
if ( init_level == PAPI_NOT_INITED )
papi_return( PAPI_ENOINIT );
if ( tag & PAPI_TLS_ALL_THREADS ) {
tag = tag ^ PAPI_TLS_ALL_THREADS;
doall = 1;
}
if ( ( tag < 0 ) || ( tag > PAPI_TLS_NUM ) )
papi_return( PAPI_EINVAL );
if ( doall )
papi_return( _papi_hwi_gather_all_thrspec_data
( tag, ( PAPI_all_thr_spec_t * ) ptr ) );
retval = _papi_hwi_lookup_or_create_thread( &thread, 0 );
if ( retval == PAPI_OK )
*ptr = thread->thread_storage[tag];
else
papi_return( retval );
return ( PAPI_OK );
}
| long long PAPI_get_virt_cyc | ( | void | ) |
return the process cycles since some arbitrary starting point
Definition at line 6176 of file papi.c.
{
return ( ( long long ) _papi_os_vector.get_virt_cycles( ) );
}
| long long PAPI_get_virt_nsec | ( | void | ) |
return the process nanoseconds since some arbitrary starting point
Definition at line 6206 of file papi.c.
{
return ( ( _papi_os_vector.get_virt_nsec()));
}
| long long PAPI_get_virt_usec | ( | void | ) |
return the process microseconds since some arbitrary starting point
Definition at line 6248 of file papi.c.
{
return ( ( long long ) _papi_os_vector.get_virt_usec() );
}
| int PAPI_is_initialized | ( | void | ) |
return the initialized state of the PAPI library
Definition at line 6341 of file papi.c.
{
return ( init_level );
}
| int PAPI_library_init | ( | int | version | ) |
initialize the PAPI library
Definition at line 498 of file papi.c.
{
char *filename;
int tmp = 0, tmpel;
/* This is a poor attempt at a lock.
For 3.1 this should be replaced with a
true UNIX semaphore. We cannot use PAPI
locks here because they are not initialized yet */
static int _in_papi_library_init_cnt = 0;
#ifdef DEBUG
char *var;
#endif
_papi_hwi_init_errors();
if ( version != PAPI_VER_CURRENT )
papi_return( PAPI_EINVAL );
++_in_papi_library_init_cnt;
while ( _in_papi_library_init_cnt > 1 ) {
PAPIERROR( "Multiple callers of PAPI_library_init" );
sleep( 1 );
}
/* This checks to see if we have forked or called init more than once.
If we have forked, then we continue to init. If we have not forked,
we check to see the status of initialization. */
APIDBG( "Initializing library: current PID %d, old PID %d\n",
getpid( ), _papi_hwi_system_info.pid );
if ( _papi_hwi_system_info.pid == getpid( ) ) {
/* If the magic environment variable PAPI_ALLOW_STOLEN is set,
we call shutdown if PAPI has been initialized. This allows
tools that use LD_PRELOAD to run on applications that use PAPI.
In this circumstance, PAPI_ALLOW_STOLEN will be set to 'stolen'
so the tool can check for this case. */
if ( getenv( "PAPI_ALLOW_STOLEN" ) ) {
char buf[PAPI_HUGE_STR_LEN];
if ( init_level != PAPI_NOT_INITED )
PAPI_shutdown( );
sprintf( buf, "%s=%s", "PAPI_ALLOW_STOLEN", "stolen" );
putenv( buf );
}
/* If the library has been successfully initialized *OR*
the library attempted initialization but failed. */
else if ( ( init_level != PAPI_NOT_INITED ) ||
( init_retval != DEADBEEF ) ) {
_in_papi_library_init_cnt--;
if ( init_retval < PAPI_OK )
papi_return( init_retval );
else
return ( init_retval );
}
APIDBG( "system_info was initialized, but init did not succeed\n" );
}
#ifdef DEBUG
var = ( char * ) getenv( "PAPI_DEBUG" );
_papi_hwi_debug = 0;
if ( var != NULL ) {
if ( strlen( var ) != 0 ) {
if ( strstr( var, "SUBSTRATE" ) )
_papi_hwi_debug |= DEBUG_SUBSTRATE;
if ( strstr( var, "API" ) )
_papi_hwi_debug |= DEBUG_API;
if ( strstr( var, "INTERNAL" ) )
_papi_hwi_debug |= DEBUG_INTERNAL;
if ( strstr( var, "THREADS" ) )
_papi_hwi_debug |= DEBUG_THREADS;
if ( strstr( var, "MULTIPLEX" ) )
_papi_hwi_debug |= DEBUG_MULTIPLEX;
if ( strstr( var, "OVERFLOW" ) )
_papi_hwi_debug |= DEBUG_OVERFLOW;
if ( strstr( var, "PROFILE" ) )
_papi_hwi_debug |= DEBUG_PROFILE;
if ( strstr( var, "MEMORY" ) )
_papi_hwi_debug |= DEBUG_MEMORY;
if ( strstr( var, "LEAK" ) )
_papi_hwi_debug |= DEBUG_LEAK;
if ( strstr( var, "ALL" ) )
_papi_hwi_debug |= DEBUG_ALL;
}
if ( _papi_hwi_debug == 0 )
_papi_hwi_debug |= DEBUG_API;
}
#endif
/* Be verbose for now */
tmpel = _papi_hwi_error_level;
_papi_hwi_error_level = PAPI_VERB_ECONT;
/* Initialize internal globals */
if ( _papi_hwi_init_global_internal( ) != PAPI_OK ) {
_in_papi_library_init_cnt--;
_papi_hwi_error_level = tmpel;
papi_return( PAPI_EINVAL );
}
/* Initialize OS */
tmp = _papi_hwi_init_os();
if ( tmp ) {
init_retval = tmp;
_papi_hwi_shutdown_global_internal( );
_in_papi_library_init_cnt--;
_papi_hwi_error_level = tmpel;
papi_return( init_retval );
}
/* Initialize component globals */
tmp = _papi_hwi_init_global( );
if ( tmp ) {
init_retval = tmp;
_papi_hwi_shutdown_global_internal( );
_in_papi_library_init_cnt--;
_papi_hwi_error_level = tmpel;
papi_return( init_retval );
}
/* Initialize thread globals, including the main threads */
tmp = _papi_hwi_init_global_threads( );
if ( tmp ) {
int i;
init_retval = tmp;
_papi_hwi_shutdown_global_internal( );
for ( i = 0; i < papi_num_components; i++ ) {
if (!_papi_hwd[i]->cmp_info.disabled) {
_papi_hwd[i]->shutdown_component( );
}
}
_in_papi_library_init_cnt--;
_papi_hwi_error_level = tmpel;
papi_return( init_retval );
}
init_level = PAPI_LOW_LEVEL_INITED;
_in_papi_library_init_cnt--;
_papi_hwi_error_level = tmpel;
#ifdef STATIC_USER_EVENTS
_papi_user_defined_events_setup(NULL);
#endif
if ( (filename = getenv( "PAPI_USER_EVENTS_FILE" )) != NULL ) {
_papi_user_defined_events_setup(filename);
}
return ( init_retval = PAPI_VER_CURRENT );
}
| int PAPI_list_events | ( | int | EventSet, |
| int * | Events, | ||
| int * | number | ||
| ) |
list the events that are members of an event set
Definition at line 5883 of file papi.c.
{
EventSetInfo_t *ESI;
int i, j;
if ( ( Events == NULL ) || ( *number <= 0 ) )
papi_return( PAPI_EINVAL );
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( !ESI )
papi_return( PAPI_ENOEVST );
for ( i = 0, j = 0; j < ESI->NumberOfEvents; i++ ) {
if ( ( int ) ESI->EventInfoArray[i].event_code != PAPI_NULL ) {
Events[j] = ( int ) ESI->EventInfoArray[i].event_code;
j++;
if ( j == *number )
break;
}
}
*number = j;
return ( PAPI_OK );
}
| int PAPI_list_threads | ( | unsigned long * | tids, |
| int * | number | ||
| ) |
list the thread ids currently known to PAPI
Definition at line 284 of file papi.c.
{
PAPI_all_thr_spec_t tmp;
int retval;
/* If tids == NULL, then just count the threads, don't gather a list. */
/* If tids != NULL, then we need the length of the tids array in num. */
if ( ( number == NULL ) || ( tids && ( *number <= 0 ) ) )
papi_return( PAPI_EINVAL );
memset( &tmp, 0x0, sizeof ( tmp ) );
/* data == NULL, since we don't want the thread specific pointers. */
/* tids may be NULL, if the user doesn't want the thread IDs. */
tmp.num = *number;
tmp.id = tids;
tmp.data = NULL;
retval = _papi_hwi_gather_all_thrspec_data( 0, &tmp );
if ( retval == PAPI_OK )
*number = tmp.num;
papi_return( retval );
}
| int PAPI_lock | ( | int | ) |
lock one of two PAPI internal user mutex variables
Definition at line 6279 of file papi.c.
{
if ( ( lck < 0 ) || ( lck >= PAPI_NUM_LOCK ) )
papi_return( PAPI_EINVAL );
papi_return( _papi_hwi_lock( lck ) );
}
| int PAPI_multiplex_init | ( | void | ) |
initialize multiplex support in the PAPI library
Definition at line 2907 of file papi.c.
{
int retval;
retval = mpx_init( _papi_os_info.itimer_ns );
papi_return( retval );
}
| int PAPI_num_cmp_hwctrs | ( | int | cidx | ) |
return the number of hardware counters for a specified component
Definition at line 3880 of file papi.c.
{
return ( PAPI_get_cmp_opt( PAPI_MAX_HWCTRS, NULL, cidx ) );
}
| int PAPI_num_events | ( | int | EventSet | ) |
return the number of events in an event set
Definition at line 4338 of file papi.c.
{
EventSetInfo_t *ESI;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( !ESI )
papi_return( PAPI_ENOEVST );
#ifdef DEBUG
/* Not necessary */
if ( ESI->NumberOfEvents == 0 )
papi_return( PAPI_EINVAL );
#endif
return ( ESI->NumberOfEvents );
}
| int PAPI_overflow | ( | int | EventSet, |
| int | EventCode, | ||
| int | threshold, | ||
| int | flags, | ||
| PAPI_overflow_handler_t | handler | ||
| ) |
set up an event set to begin registering overflows
< Using Hardware
< Force using Software
Definition at line 4684 of file papi.c.
{
int retval, cidx, index, i;
EventSetInfo_t *ESI;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL ) {
OVFDBG("No EventSet\n");
papi_return( PAPI_ENOEVST );
}
cidx = valid_ESI_component( ESI );
if ( cidx < 0 ) {
OVFDBG("Component Error\n");
papi_return( cidx );
}
if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
OVFDBG("Already running\n");
papi_return( PAPI_EISRUN );
}
if ( ESI->state & PAPI_ATTACHED ) {
OVFDBG("Attached\n");
papi_return( PAPI_EINVAL );
}
if ( ESI->state & PAPI_CPU_ATTACHED ) {
OVFDBG("CPU attached\n");
papi_return( PAPI_EINVAL );
}
if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
( unsigned int ) EventCode ) ) < 0 ) {
papi_return( PAPI_ENOEVNT );
}
if ( threshold < 0 ) {
OVFDBG("Threshold below zero\n");
papi_return( PAPI_EINVAL );
}
/* We do not support derived events in overflow */
/* Unless it's DERIVED_CMPD in which no calculations are done */
if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) && threshold != 0 &&
( ESI->EventInfoArray[index].derived ) &&
( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) ) {
OVFDBG("Derived event in overflow\n");
papi_return( PAPI_EINVAL );
}
/* the first time to call PAPI_overflow function */
if ( !( ESI->state & PAPI_OVERFLOWING ) ) {
if ( handler == NULL ) {
OVFDBG("NULL handler\n");
papi_return( PAPI_EINVAL );
}
if ( threshold == 0 ) {
OVFDBG("Zero threshold\n");
papi_return( PAPI_EINVAL );
}
}
if ( threshold > 0 &&
ESI->overflow.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs )
papi_return( PAPI_ECNFLCT );
if ( threshold == 0 ) {
for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
if ( ESI->overflow.EventCode[i] == EventCode )
break;
}
/* EventCode not found */
if ( i == ESI->overflow.event_counter )
papi_return( PAPI_EINVAL );
/* compact these arrays */
while ( i < ESI->overflow.event_counter - 1 ) {
ESI->overflow.deadline[i] = ESI->overflow.deadline[i + 1];
ESI->overflow.threshold[i] = ESI->overflow.threshold[i + 1];
ESI->overflow.EventIndex[i] = ESI->overflow.EventIndex[i + 1];
ESI->overflow.EventCode[i] = ESI->overflow.EventCode[i + 1];
i++;
}
ESI->overflow.deadline[i] = 0;
ESI->overflow.threshold[i] = 0;
ESI->overflow.EventIndex[i] = 0;
ESI->overflow.EventCode[i] = 0;
ESI->overflow.event_counter--;
} else {
if ( ESI->overflow.event_counter > 0 ) {
if ( ( flags & PAPI_OVERFLOW_FORCE_SW ) &&
( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) )
papi_return( PAPI_ECNFLCT );
if ( !( flags & PAPI_OVERFLOW_FORCE_SW ) &&
( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) )
papi_return( PAPI_ECNFLCT );
}
for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
if ( ESI->overflow.EventCode[i] == EventCode )
break;
}
/* A new entry */
if ( i == ESI->overflow.event_counter ) {
ESI->overflow.EventCode[i] = EventCode;
ESI->overflow.event_counter++;
}
/* New or existing entry */
ESI->overflow.deadline[i] = threshold;
ESI->overflow.threshold[i] = threshold;
ESI->overflow.EventIndex[i] = index;
ESI->overflow.flags = flags;
}
/* If overflowing is already active, we should check to
make sure that we don't specify a different handler
or different flags here. You can't mix them. */
ESI->overflow.handler = handler;
/* Set up the option structure for the low level.
If we have hardware interrupts and we are not using
forced software emulated interrupts */
if ( _papi_hwd[cidx]->cmp_info.hardware_intr &&
!( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) ) {
retval = _papi_hwd[cidx]->set_overflow( ESI, index, threshold );
if ( retval == PAPI_OK )
ESI->overflow.flags |= PAPI_OVERFLOW_HARDWARE;
else {
papi_return( retval ); /* We should undo stuff here */
}
} else {
/* Make sure hardware overflow is not set */
ESI->overflow.flags &= ~( PAPI_OVERFLOW_HARDWARE );
}
APIDBG( "Overflow using: %s\n",
( ESI->overflow.
flags & PAPI_OVERFLOW_HARDWARE ? "[Hardware]" : ESI->overflow.
flags & PAPI_OVERFLOW_FORCE_SW ? "[Forced Software]" :
"[Software]" ) );
/* Toggle the overflow flags and ESI state */
if ( ESI->overflow.event_counter >= 1 )
ESI->state |= PAPI_OVERFLOWING;
else {
ESI->state ^= PAPI_OVERFLOWING;
ESI->overflow.flags = 0;
ESI->overflow.handler = NULL;
}
return PAPI_OK;
}
| void PAPI_perror | ( | char * | msg | ) |
Print a PAPI error message
Definition at line 4548 of file papi.c.
{
char *foo;
foo = PAPI_strerror( _papi_hwi_errno );
if ( foo == NULL )
return;
if ( msg )
if ( *msg )
fprintf( stderr, "%s: ", msg );
fprintf( stderr, "%s\n", foo );
}
| int PAPI_profil | ( | void * | buf, |
| unsigned | bufsiz, | ||
| caddr_t | offset, | ||
| unsigned | scale, | ||
| int | EventSet, | ||
| int | EventCode, | ||
| int | threshold, | ||
| int | flags | ||
| ) |
generate PC histogram data where hardware counter overflow occurs
Definition at line 5332 of file papi.c.
{
EventSetInfo_t *ESI;
int i;
int retval;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/* scale factors are checked for validity in PAPI_sprofil */
if ( threshold > 0 ) {
PAPI_sprofil_t *prof;
for ( i = 0; i < ESI->profile.event_counter; i++ ) {
if ( ESI->profile.EventCode[i] == EventCode )
break;
}
if ( i == ESI->profile.event_counter ) {
prof =
( PAPI_sprofil_t * ) papi_malloc( sizeof ( PAPI_sprofil_t ) );
memset( prof, 0x0, sizeof ( PAPI_sprofil_t ) );
prof->pr_base = buf;
prof->pr_size = bufsiz;
prof->pr_off = offset;
prof->pr_scale = scale;
retval =
PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
if ( retval != PAPI_OK )
papi_free( prof );
} else {
prof = ESI->profile.prof[i];
prof->pr_base = buf;
prof->pr_size = bufsiz;
prof->pr_off = offset;
prof->pr_scale = scale;
retval =
PAPI_sprofil( prof, 1, EventSet, EventCode, threshold, flags );
}
papi_return( retval );
}
for ( i = 0; i < ESI->profile.event_counter; i++ ) {
if ( ESI->profile.EventCode[i] == EventCode )
break;
}
/* EventCode not found */
if ( i == ESI->profile.event_counter )
papi_return( PAPI_EINVAL );
papi_free( ESI->profile.prof[i] );
ESI->profile.prof[i] = NULL;
papi_return( PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, flags ) );
}
| int PAPI_query_event | ( | int | EventCode | ) |
query if a PAPI event exists
Definition at line 700 of file papi.c.
{
if ( IS_PRESET(EventCode) ) {
EventCode &= PAPI_PRESET_AND_MASK;
if ( EventCode >= PAPI_MAX_PRESET_EVENTS )
papi_return( PAPI_ENOTPRESET );
if ( _papi_hwi_presets[EventCode].count )
papi_return (PAPI_OK);
else
return PAPI_ENOEVNT;
}
if ( IS_NATIVE(EventCode) ) {
papi_return( _papi_hwi_query_native_event
( ( unsigned int ) EventCode ) );
}
if ( IS_USER_DEFINED(EventCode) ) {
EventCode &= PAPI_UE_AND_MASK;
if ( EventCode < 0 || EventCode > (int)_papi_user_events_count)
return ( PAPI_EINVAL );
papi_return( PAPI_OK );
}
papi_return( PAPI_ENOEVNT );
}
| int PAPI_query_named_event | ( | char * | EventName | ) |
query if a named PAPI event exists
Definition at line 770 of file papi.c.
{
int ret, code;
ret = PAPI_event_name_to_code( EventName, &code );
if ( ret == PAPI_OK ) ret = PAPI_query_event( code );
papi_return( ret);
}
| int PAPI_read | ( | int | EventSet, |
| long long * | values | ||
| ) |
read hardware events from an event set with no reset
Definition at line 2485 of file papi.c.
{
EventSetInfo_t *ESI;
hwd_context_t *context;
int cidx, retval = PAPI_OK;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( values == NULL )
papi_return( PAPI_EINVAL );
if ( ESI->state & PAPI_RUNNING ) {
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
retval = MPX_read( ESI->multiplex.mpx_evset, values, 0 );
} else {
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, NULL );
retval = _papi_hwi_read( context, ESI, values );
}
if ( retval != PAPI_OK )
papi_return( retval );
} else {
memcpy( values, ESI->sw_stop,
( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
}
#if defined(DEBUG)
if ( ISLEVEL( DEBUG_API ) ) {
int i;
for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
}
}
#endif
APIDBG( "PAPI_read returns %d\n", retval );
return ( PAPI_OK );
}
| int PAPI_read_ts | ( | int | EventSet, |
| long long * | values, | ||
| long long * | cyc | ||
| ) |
read from an eventset with a real-time cycle timestamp
Definition at line 2575 of file papi.c.
{
EventSetInfo_t *ESI;
hwd_context_t *context;
int cidx, retval = PAPI_OK;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( values == NULL )
papi_return( PAPI_EINVAL );
if ( ESI->state & PAPI_RUNNING ) {
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
retval = MPX_read( ESI->multiplex.mpx_evset, values, 0 );
} else {
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, NULL );
retval = _papi_hwi_read( context, ESI, values );
}
if ( retval != PAPI_OK )
papi_return( retval );
} else {
memcpy( values, ESI->sw_stop,
( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
}
*cycles = _papi_os_vector.get_real_cycles( );
#if defined(DEBUG)
if ( ISLEVEL( DEBUG_API ) ) {
int i;
for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
APIDBG( "PAPI_read values[%d]:\t%lld\n", i, values[i] );
}
}
#endif
APIDBG( "PAPI_read_ts returns %d\n", retval );
return PAPI_OK;
}
| int PAPI_register_thread | ( | void | ) |
inform PAPI of the existence of a new thread
Definition at line 204 of file papi.c.
{
ThreadInfo_t *thread;
if ( init_level == PAPI_NOT_INITED )
papi_return( PAPI_ENOINIT );
papi_return( _papi_hwi_lookup_or_create_thread( &thread, 0 ) );
}
| int PAPI_remove_event | ( | int | EventSet, |
| int | EventCode | ||
| ) |
remove a hardware event from a PAPI event set
Definition at line 1707 of file papi.c.
{
EventSetInfo_t *ESI;
int i,retval;
/* check for pre-existing ESI */
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/* Check argument for validity */
if ( ( !IS_PRESET(EventCode) ) &&
( !IS_NATIVE(EventCode) ) &&
( !IS_USER_DEFINED(EventCode) ))
papi_return( PAPI_EINVAL );
/* Of course, it must be stopped in order to modify it. */
if ( !( ESI->state & PAPI_STOPPED ) )
papi_return( PAPI_EISRUN );
/* if the state is PAPI_OVERFLOWING, you must first call
PAPI_overflow with threshold=0 to remove the overflow flag */
/* Turn off the event that is overflowing */
if ( ESI->state & PAPI_OVERFLOWING ) {
for ( i = 0; i < ESI->overflow.event_counter; i++ ) {
if ( ESI->overflow.EventCode[i] == EventCode ) {
retval = PAPI_overflow( EventSet, EventCode, 0, 0,
ESI->overflow.handler );
if (retval!=PAPI_OK) return retval;
break;
}
}
}
/* force the user to call PAPI_profil to clear the PAPI_PROFILING flag */
if ( ESI->state & PAPI_PROFILING ) {
for ( i = 0; i < ESI->profile.event_counter; i++ ) {
if ( ESI->profile.EventCode[i] == EventCode ) {
PAPI_sprofil( NULL, 0, EventSet, EventCode, 0, 0 );
break;
}
}
}
/* Now do the magic. */
papi_return( _papi_hwi_remove_event( ESI, EventCode ) );
}
| int PAPI_remove_events | ( | int | EventSet, |
| int * | Events, | ||
| int | number | ||
| ) |
remove an array of hardware events from a PAPI event set
Definition at line 5823 of file papi.c.
{
int i, retval;
if ( ( Events == NULL ) || ( number <= 0 ) )
papi_return( PAPI_EINVAL );
for ( i = 0; i < number; i++ ) {
retval = PAPI_remove_event( EventSet, Events[i] );
if ( retval != PAPI_OK ) {
if ( i == 0 )
papi_return( retval );
else
return ( i );
}
}
return ( PAPI_OK );
}
| int PAPI_remove_named_event | ( | int | EventSet, |
| char * | EventName | ||
| ) |
remove a named event from a PAPI event set
Definition at line 1901 of file papi.c.
{
int ret, code;
ret = PAPI_event_name_to_code( EventName, &code );
if ( ret == PAPI_OK ) ret = PAPI_remove_event( EventSet, code );
papi_return( ret );
}
| int PAPI_reset | ( | int | EventSet | ) |
reset the hardware event counts in an event set
Definition at line 2384 of file papi.c.
{
int retval = PAPI_OK;
EventSetInfo_t *ESI;
hwd_context_t *context;
int cidx;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( ESI->state & PAPI_RUNNING ) {
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
retval = MPX_reset( ESI->multiplex.mpx_evset );
} else {
/* If we're not the only one running, then just
read the current values into the ESI->start
array. This holds the starting value for counters
that are shared. */
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, NULL );
retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
}
} else {
#ifdef __bgp__
// For BG/P, we always want to reset the 'real' hardware counters. The counters
// can be controlled via multiple interfaces, and we need to ensure that the values
// are truly zero...
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, NULL );
retval = _papi_hwd[cidx]->reset( context, ESI->ctl_state );
#endif
memset( ESI->sw_stop, 0x00,
( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
}
APIDBG( "PAPI_reset returns %d\n", retval );
papi_return( retval );
}
| int PAPI_set_cmp_domain | ( | int | domain, |
| int | cidx | ||
| ) |
set the component specific default execution domain for new event sets
Definition at line 5651 of file papi.c.
{
PAPI_option_t ptr;
memset( &ptr, 0, sizeof ( ptr ) );
ptr.defdomain.def_cidx = cidx;
ptr.defdomain.domain = domain;
papi_return( PAPI_set_opt( PAPI_DEFDOM, &ptr ) );
}
| int PAPI_set_cmp_granularity | ( | int | granularity, |
| int | cidx | ||
| ) |
set the component specific default granularity for new event sets
Definition at line 5515 of file papi.c.
{
PAPI_option_t ptr;
memset( &ptr, 0, sizeof ( ptr ) );
ptr.defgranularity.def_cidx = cidx;
ptr.defgranularity.granularity = granularity;
papi_return( PAPI_set_opt( PAPI_DEFGRN, &ptr ) );
}
| int PAPI_set_debug | ( | int | level | ) |
set the current debug level for PAPI
Definition at line 3047 of file papi.c.
{
PAPI_option_t option;
memset( &option, 0x0, sizeof ( option ) );
option.debug.level = level;
option.debug.handler = _papi_hwi_debug_handler;
return ( PAPI_set_opt( PAPI_DEBUG, &option ) );
}
| int PAPI_set_domain | ( | int | domain | ) |
set the default execution domain for new event sets
Definition at line 5581 of file papi.c.
{
return ( PAPI_set_cmp_domain( domain, 0 ) );
}
| int PAPI_set_granularity | ( | int | granularity | ) |
set the default granularity for new event sets
Definition at line 5450 of file papi.c.
{
return ( PAPI_set_cmp_granularity( granularity, 0 ) );
}
| int PAPI_set_multiplex | ( | int | EventSet | ) |
convert a standard event set to a multiplexed event set
Definition at line 3256 of file papi.c.
{
PAPI_option_t mpx;
EventSetInfo_t *ESI;
int cidx;
int ret;
/* Is the EventSet already in existence? */
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/* if the eventset has no index return NOCMP */
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( ( ret = mpx_check( EventSet ) ) != PAPI_OK )
papi_return( ret );
memset( &mpx, 0x0, sizeof ( mpx ) );
mpx.multiplex.eventset = EventSet;
mpx.multiplex.flags = PAPI_MULTIPLEX_DEFAULT;
mpx.multiplex.ns = _papi_os_info.itimer_ns;
return ( PAPI_set_opt( PAPI_MULTIPLEX, &mpx ) );
}
| int PAPI_set_opt | ( | int | option, |
| PAPI_option_t * | ptr | ||
| ) |
change the option settings of the PAPI library or a specific event set
Definition at line 3386 of file papi.c.
{
APIDBG("Entry: option: %d, ptr: %p\n", option, ptr);
_papi_int_option_t internal;
int retval = PAPI_OK;
hwd_context_t *context;
int cidx;
if ( ( option != PAPI_DEBUG ) && ( init_level == PAPI_NOT_INITED ) )
papi_return( PAPI_ENOINIT );
if ( ptr == NULL )
papi_return( PAPI_EINVAL );
memset( &internal, 0x0, sizeof ( _papi_int_option_t ) );
switch ( option ) {
case PAPI_DETACH:
{
internal.attach.ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
if ( internal.attach.ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( internal.attach.ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
papi_return( PAPI_ECMP );
/* if attached to a cpu, return an error */
if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
papi_return( PAPI_ECMP );
if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
papi_return( PAPI_EISRUN );
if ( ( internal.attach.ESI->state & PAPI_ATTACHED ) == 0 )
papi_return( PAPI_EINVAL );
internal.attach.tid = internal.attach.ESI->attach.tid;
/* get the context we should use for this event set */
context = _papi_hwi_get_context( internal.attach.ESI, NULL );
retval = _papi_hwd[cidx]->ctl( context, PAPI_DETACH, &internal );
if ( retval != PAPI_OK )
papi_return( retval );
internal.attach.ESI->state ^= PAPI_ATTACHED;
internal.attach.ESI->attach.tid = 0;
return ( PAPI_OK );
}
case PAPI_ATTACH:
{
internal.attach.ESI = _papi_hwi_lookup_EventSet( ptr->attach.eventset );
if ( internal.attach.ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( internal.attach.ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( _papi_hwd[cidx]->cmp_info.attach == 0 )
papi_return( PAPI_ECMP );
if ( ( internal.attach.ESI->state & PAPI_STOPPED ) == 0 )
papi_return( PAPI_EISRUN );
if ( internal.attach.ESI->state & PAPI_ATTACHED )
papi_return( PAPI_EINVAL );
/* if attached to a cpu, return an error */
if (internal.attach.ESI->state & PAPI_CPU_ATTACHED)
papi_return( PAPI_ECMP );
internal.attach.tid = ptr->attach.tid;
/* get the context we should use for this event set */
context = _papi_hwi_get_context( internal.attach.ESI, NULL );
retval = _papi_hwd[cidx]->ctl( context, PAPI_ATTACH, &internal );
if ( retval != PAPI_OK )
papi_return( retval );
internal.attach.ESI->state |= PAPI_ATTACHED;
internal.attach.ESI->attach.tid = ptr->attach.tid;
papi_return (_papi_hwi_lookup_or_create_thread(
&(internal.attach.ESI->master), ptr->attach.tid ));
}
case PAPI_CPU_ATTACH:
{
APIDBG("eventset: %d, cpu_num: %d\n", ptr->cpu.eventset, ptr->cpu.cpu_num);
internal.cpu.ESI = _papi_hwi_lookup_EventSet( ptr->cpu.eventset );
if ( internal.cpu.ESI == NULL )
papi_return( PAPI_ENOEVST );
internal.cpu.cpu_num = ptr->cpu.cpu_num;
APIDBG("internal: %p, ESI: %p, cpu_num: %d\n", &internal, internal.cpu.ESI, internal.cpu.cpu_num);
cidx = valid_ESI_component( internal.cpu.ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( _papi_hwd[cidx]->cmp_info.cpu == 0 )
papi_return( PAPI_ECMP );
// can not attach to a cpu if already attached to a process or
// counters set to be inherited by child processes
if ( internal.cpu.ESI->state & (PAPI_ATTACHED | PAPI_INHERIT) )
papi_return( PAPI_EINVAL );
if ( ( internal.cpu.ESI->state & PAPI_STOPPED ) == 0 )
papi_return( PAPI_EISRUN );
retval = _papi_hwi_lookup_or_create_cpu(&internal.cpu.ESI->CpuInfo, internal.cpu.cpu_num);
if( retval != PAPI_OK) {
papi_return( retval );
}
/* get the context we should use for this event set */
context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
retval = _papi_hwd[cidx]->ctl( context, PAPI_CPU_ATTACH, &internal );
if ( retval != PAPI_OK )
papi_return( retval );
/* set to show this event set is attached to a cpu not a thread */
internal.cpu.ESI->state |= PAPI_CPU_ATTACHED;
return ( PAPI_OK );
}
case PAPI_DEF_MPX_NS:
{
cidx = 0; /* xxxx for now, assume we only check against cpu component */
if ( ptr->multiplex.ns < 0 )
papi_return( PAPI_EINVAL );
/* We should check the resolution here with the system, either
component if kernel multiplexing or PAPI if SW multiplexing. */
internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
/* get the context we should use for this event set */
context = _papi_hwi_get_context( internal.cpu.ESI, NULL );
/* Low level just checks/adjusts the args for this component */
retval = _papi_hwd[cidx]->ctl( context, PAPI_DEF_MPX_NS, &internal );
if ( retval == PAPI_OK ) {
_papi_os_info.itimer_ns = ( int ) internal.multiplex.ns;
ptr->multiplex.ns = ( int ) internal.multiplex.ns;
}
papi_return( retval );
}
case PAPI_DEF_ITIMER_NS:
{
cidx = 0; /* xxxx for now, assume we only check against cpu component */
if ( ptr->itimer.ns < 0 )
papi_return( PAPI_EINVAL );
internal.itimer.ns = ptr->itimer.ns;
/* Low level just checks/adjusts the args for this component */
retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER_NS, &internal );
if ( retval == PAPI_OK ) {
_papi_os_info.itimer_ns = internal.itimer.ns;
ptr->itimer.ns = internal.itimer.ns;
}
papi_return( retval );
}
case PAPI_DEF_ITIMER:
{
cidx = 0; /* xxxx for now, assume we only check against cpu component */
if ( ptr->itimer.ns < 0 )
papi_return( PAPI_EINVAL );
memcpy( &internal.itimer, &ptr->itimer,
sizeof ( PAPI_itimer_option_t ) );
/* Low level just checks/adjusts the args for this component */
retval = _papi_hwd[cidx]->ctl( NULL, PAPI_DEF_ITIMER, &internal );
if ( retval == PAPI_OK ) {
_papi_os_info.itimer_num = ptr->itimer.itimer_num;
_papi_os_info.itimer_sig = ptr->itimer.itimer_sig;
if ( ptr->itimer.ns > 0 )
_papi_os_info.itimer_ns = ptr->itimer.ns;
/* flags are currently ignored, eventually the flags will be able
to specify whether or not we use POSIX itimers (clock_gettimer) */
}
papi_return( retval );
}
case PAPI_MULTIPLEX:
{
EventSetInfo_t *ESI;
ESI = _papi_hwi_lookup_EventSet( ptr->multiplex.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( !( ESI->state & PAPI_STOPPED ) )
papi_return( PAPI_EISRUN );
if ( ESI->state & PAPI_MULTIPLEXING )
papi_return( PAPI_EINVAL );
if ( ptr->multiplex.ns < 0 )
papi_return( PAPI_EINVAL );
internal.multiplex.ESI = ESI;
internal.multiplex.ns = ( unsigned long ) ptr->multiplex.ns;
internal.multiplex.flags = ptr->multiplex.flags;
if ( ( _papi_hwd[cidx]->cmp_info.kernel_multiplex ) &&
( ( ptr->multiplex.flags & PAPI_MULTIPLEX_FORCE_SW ) == 0 ) ) {
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, NULL );
retval = _papi_hwd[cidx]->ctl( context, PAPI_MULTIPLEX, &internal );
}
/* Kernel or PAPI may have changed this value so send it back out to the user */
ptr->multiplex.ns = ( int ) internal.multiplex.ns;
if ( retval == PAPI_OK )
papi_return( _papi_hwi_convert_eventset_to_multiplex
( &internal.multiplex ) );
return ( retval );
}
case PAPI_DEBUG:
{
int level = ptr->debug.level;
switch ( level ) {
case PAPI_QUIET:
case PAPI_VERB_ESTOP:
case PAPI_VERB_ECONT:
_papi_hwi_error_level = level;
break;
default:
papi_return( PAPI_EINVAL );
}
_papi_hwi_debug_handler = ptr->debug.handler;
return ( PAPI_OK );
}
case PAPI_DEFDOM:
{
int dom = ptr->defdomain.domain;
if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
papi_return( PAPI_EINVAL );
/* Change the global structure. The _papi_hwd_init_control_state function
in the components gets information from the global structure instead of
per-thread information. */
cidx = valid_component( ptr->defdomain.def_cidx );
if ( cidx < 0 )
papi_return( cidx );
/* Check what the component supports */
if ( dom == PAPI_DOM_ALL )
dom = _papi_hwd[cidx]->cmp_info.available_domains;
if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
papi_return( PAPI_EINVAL );
_papi_hwd[cidx]->cmp_info.default_domain = dom;
return ( PAPI_OK );
}
case PAPI_DOMAIN:
{
int dom = ptr->domain.domain;
if ( ( dom < PAPI_DOM_MIN ) || ( dom > PAPI_DOM_MAX ) )
papi_return( PAPI_EINVAL_DOM );
internal.domain.ESI = _papi_hwi_lookup_EventSet( ptr->domain.eventset );
if ( internal.domain.ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( internal.domain.ESI );
if ( cidx < 0 )
papi_return( cidx );
/* Check what the component supports */
if ( dom == PAPI_DOM_ALL )
dom = _papi_hwd[cidx]->cmp_info.available_domains;
if ( dom & ~_papi_hwd[cidx]->cmp_info.available_domains )
papi_return( PAPI_EINVAL_DOM );
if ( !( internal.domain.ESI->state & PAPI_STOPPED ) )
papi_return( PAPI_EISRUN );
/* Try to change the domain of the eventset in the hardware */
internal.domain.domain = dom;
internal.domain.eventset = ptr->domain.eventset;
/* get the context we should use for this event set */
context = _papi_hwi_get_context( internal.domain.ESI, NULL );
retval = _papi_hwd[cidx]->ctl( context, PAPI_DOMAIN, &internal );
if ( retval < PAPI_OK )
papi_return( retval );
/* Change the domain of the eventset in the library */
internal.domain.ESI->domain.domain = dom;
return ( retval );
}
case PAPI_DEFGRN:
{
int grn = ptr->defgranularity.granularity;
if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
papi_return( PAPI_EINVAL );
cidx = valid_component( ptr->defgranularity.def_cidx );
if ( cidx < 0 )
papi_return( cidx );
/* Change the component structure. The _papi_hwd_init_control_state function
in the components gets information from the global structure instead of
per-thread information. */
/* Check what the component supports */
if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
papi_return( PAPI_EINVAL );
/* Make sure there is only 1 set. */
if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
papi_return( PAPI_EINVAL );
_papi_hwd[cidx]->cmp_info.default_granularity = grn;
return ( PAPI_OK );
}
case PAPI_GRANUL:
{
int grn = ptr->granularity.granularity;
if ( ( grn < PAPI_GRN_MIN ) || ( grn > PAPI_GRN_MAX ) )
papi_return( PAPI_EINVAL );
internal.granularity.ESI =
_papi_hwi_lookup_EventSet( ptr->granularity.eventset );
if ( internal.granularity.ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( internal.granularity.ESI );
if ( cidx < 0 )
papi_return( cidx );
/* Check what the component supports */
if ( grn & ~_papi_hwd[cidx]->cmp_info.available_granularities )
papi_return( PAPI_EINVAL );
/* Make sure there is only 1 set. */
if ( grn ^ ( 1 << ( ffs( grn ) - 1 ) ) )
papi_return( PAPI_EINVAL );
internal.granularity.granularity = grn;
internal.granularity.eventset = ptr->granularity.eventset;
retval = _papi_hwd[cidx]->ctl( NULL, PAPI_GRANUL, &internal );
if ( retval < PAPI_OK )
return ( retval );
internal.granularity.ESI->granularity.granularity = grn;
return ( retval );
}
case PAPI_INHERIT:
{
EventSetInfo_t *ESI;
ESI = _papi_hwi_lookup_EventSet( ptr->inherit.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( _papi_hwd[cidx]->cmp_info.inherit == 0 )
papi_return( PAPI_ECMP );
if ( ( ESI->state & PAPI_STOPPED ) == 0 )
papi_return( PAPI_EISRUN );
/* if attached to a cpu, return an error */
if (ESI->state & PAPI_CPU_ATTACHED)
papi_return( PAPI_ECMP );
internal.inherit.ESI = ESI;
internal.inherit.inherit = ptr->inherit.inherit;
/* get the context we should use for this event set */
context = _papi_hwi_get_context( internal.inherit.ESI, NULL );
retval = _papi_hwd[cidx]->ctl( context, PAPI_INHERIT, &internal );
if ( retval < PAPI_OK )
return ( retval );
ESI->inherit.inherit = ptr->inherit.inherit;
return ( retval );
}
case PAPI_DATA_ADDRESS:
case PAPI_INSTR_ADDRESS:
{
EventSetInfo_t *ESI;
ESI = _papi_hwi_lookup_EventSet( ptr->addr.eventset );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
internal.address_range.ESI = ESI;
if ( !( internal.address_range.ESI->state & PAPI_STOPPED ) )
papi_return( PAPI_EISRUN );
/*set domain to be PAPI_DOM_USER */
internal.address_range.domain = PAPI_DOM_USER;
internal.address_range.start = ptr->addr.start;
internal.address_range.end = ptr->addr.end;
/* get the context we should use for this event set */
context = _papi_hwi_get_context( internal.address_range.ESI, NULL );
retval = _papi_hwd[cidx]->ctl( context, option, &internal );
ptr->addr.start_off = internal.address_range.start_off;
ptr->addr.end_off = internal.address_range.end_off;
papi_return( retval );
}
case PAPI_USER_EVENTS_FILE:
{
SUBDBG("Filename is -%s-\n", ptr->events_file);
_papi_user_defined_events_setup(ptr->events_file);
return( PAPI_OK );
}
default:
papi_return( PAPI_EINVAL );
}
}
| int PAPI_set_thr_specific | ( | int | tag, |
| void * | ptr | ||
| ) |
save a pointer as a thread specific stored data structure
Definition at line 436 of file papi.c.
{
ThreadInfo_t *thread;
int retval = PAPI_OK;
if ( init_level == PAPI_NOT_INITED )
papi_return( PAPI_ENOINIT );
if ( ( tag < 0 ) || ( tag > PAPI_NUM_TLS ) )
papi_return( PAPI_EINVAL );
retval = _papi_hwi_lookup_or_create_thread( &thread, 0 );
if ( retval == PAPI_OK ) {
_papi_hwi_lock( THREADS_LOCK );
thread->thread_storage[tag] = ptr;
_papi_hwi_unlock( THREADS_LOCK );
}
else
return ( retval );
return ( PAPI_OK );
}
| void PAPI_shutdown | ( | void | ) |
finish using PAPI and free all related resources
Definition at line 4372 of file papi.c.
{
EventSetInfo_t *ESI;
ThreadInfo_t *master;
DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
int i, j = 0, retval;
APIDBG( "Enter\n" );
if ( init_retval == DEADBEEF ) {
PAPIERROR( PAPI_SHUTDOWN_str );
return;
}
MPX_shutdown( );
/* Free all EventSets for this thread */
master = _papi_hwi_lookup_thread( 0 );
/* Count number of running EventSets AND */
/* Stop any running EventSets in this thread */
#ifdef DEBUG
again:
#endif
for( i = 0; i < map->totalSlots; i++ ) {
ESI = map->dataSlotArray[i];
if ( ESI ) {
if ( ESI->master == master ) {
if ( ESI->state & PAPI_RUNNING ) {
retval=PAPI_stop( i, NULL );
}
retval=PAPI_cleanup_eventset( i );
if (retval!=PAPI_OK) PAPIERROR("Error during cleanup.\n");
_papi_hwi_free_EventSet( ESI );
}
else {
if ( ESI->state & PAPI_RUNNING ) {
j++;
}
}
}
}
/* No locking required, we're just waiting for the others
to call shutdown or stop their eventsets. */
#ifdef DEBUG
if ( j != 0 ) {
PAPIERROR( PAPI_SHUTDOWN_SYNC_str );
sleep( 1 );
j = 0;
goto again;
}
#endif
/* Shutdown the entire component */
_papi_cleanup_user_events();
_papi_hwi_shutdown_highlevel( );
_papi_hwi_shutdown_global_internal( );
_papi_hwi_shutdown_global_threads( );
for( i = 0; i < papi_num_components; i++ ) {
if (!_papi_hwd[i]->cmp_info.disabled) {
_papi_hwd[i]->shutdown_component( );
}
}
/* Now it is safe to call re-init */
init_retval = DEADBEEF;
init_level = PAPI_NOT_INITED;
_papi_mem_cleanup_all( );
}
| int PAPI_sprofil | ( | PAPI_sprofil_t * | prof, |
| int | profcnt, | ||
| int | EventSet, | ||
| int | EventCode, | ||
| int | threshold, | ||
| int | flags | ||
| ) |
generate hardware counter profiles from multiple code regions
Definition at line 4939 of file papi.c.
{
EventSetInfo_t *ESI;
int retval, index, i, buckets;
int forceSW = 0;
int cidx;
/* Check to make sure EventSet exists */
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL ) {
papi_return( PAPI_ENOEVST );
}
/* Check to make sure EventSet is stopped */
if ( ( ESI->state & PAPI_STOPPED ) != PAPI_STOPPED ) {
papi_return( PAPI_EISRUN );
}
/* We cannot profile if attached */
if ( ESI->state & PAPI_ATTACHED ) {
papi_return( PAPI_EINVAL );
}
/* We cannot profile if cpu attached */
if ( ESI->state & PAPI_CPU_ATTACHED ) {
papi_return( PAPI_EINVAL );
}
/* Get component for EventSet */
cidx = valid_ESI_component( ESI );
if ( cidx < 0 ) {
papi_return( cidx );
}
/* Get index of the Event we want to profile */
if ( ( index = _papi_hwi_lookup_EventCodeIndex( ESI,
(unsigned int) EventCode ) ) < 0 ) {
papi_return( PAPI_ENOEVNT );
}
/* We do not support derived events in overflow */
/* Unless it's DERIVED_CMPD in which no calculations are done */
if ( ( ESI->EventInfoArray[index].derived ) &&
( ESI->EventInfoArray[index].derived != DERIVED_CMPD ) &&
!( flags & PAPI_PROFIL_FORCE_SW ) ) {
papi_return( PAPI_EINVAL );
}
/* If no prof structures, then make sure count is 0 */
if ( prof == NULL ) {
profcnt = 0;
}
/* check all profile regions for valid scale factors of:
2 (131072/65536),
1 (65536/65536),
or < 1 (65535 -> 2) as defined in unix profil()
2/65536 is reserved for single bucket profiling
{0,1}/65536 are traditionally used to terminate profiling
but are unused here since PAPI uses threshold instead
*/
for( i = 0; i < profcnt; i++ ) {
if ( !( ( prof[i].pr_scale == 131072 ) ||
( ( prof[i].pr_scale <= 65536 && prof[i].pr_scale > 1 ) ) ) ) {
APIDBG( "Improper scale factor: %d\n", prof[i].pr_scale );
papi_return( PAPI_EINVAL );
}
}
/* Make sure threshold is valid */
if ( threshold < 0 ) {
papi_return( PAPI_EINVAL );
}
/* the first time to call PAPI_sprofil */
if ( !( ESI->state & PAPI_PROFILING ) ) {
if ( threshold == 0 ) {
papi_return( PAPI_EINVAL );
}
}
/* ??? */
if ( (threshold > 0) &&
(ESI->profile.event_counter >= _papi_hwd[cidx]->cmp_info.num_cntrs) ) {
papi_return( PAPI_ECNFLCT );
}
if ( threshold == 0 ) {
for( i = 0; i < ESI->profile.event_counter; i++ ) {
if ( ESI->profile.EventCode[i] == EventCode ) {
break;
}
}
/* EventCode not found */
if ( i == ESI->profile.event_counter ) {
papi_return( PAPI_EINVAL );
}
/* compact these arrays */
while ( i < ESI->profile.event_counter - 1 ) {
ESI->profile.prof[i] = ESI->profile.prof[i + 1];
ESI->profile.count[i] = ESI->profile.count[i + 1];
ESI->profile.threshold[i] = ESI->profile.threshold[i + 1];
ESI->profile.EventIndex[i] = ESI->profile.EventIndex[i + 1];
ESI->profile.EventCode[i] = ESI->profile.EventCode[i + 1];
i++;
}
ESI->profile.prof[i] = NULL;
ESI->profile.count[i] = 0;
ESI->profile.threshold[i] = 0;
ESI->profile.EventIndex[i] = 0;
ESI->profile.EventCode[i] = 0;
ESI->profile.event_counter--;
} else {
if ( ESI->profile.event_counter > 0 ) {
if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
!( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
papi_return( PAPI_ECNFLCT );
}
if ( !( flags & PAPI_PROFIL_FORCE_SW ) &&
( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
papi_return( PAPI_ECNFLCT );
}
}
for( i = 0; i < ESI->profile.event_counter; i++ ) {
if ( ESI->profile.EventCode[i] == EventCode ) {
break;
}
}
if ( i == ESI->profile.event_counter ) {
i = ESI->profile.event_counter;
ESI->profile.event_counter++;
ESI->profile.EventCode[i] = EventCode;
}
ESI->profile.prof[i] = prof;
ESI->profile.count[i] = profcnt;
ESI->profile.threshold[i] = threshold;
ESI->profile.EventIndex[i] = index;
}
APIDBG( "Profile event counter is %d\n", ESI->profile.event_counter );
/* Clear out old flags */
if ( threshold == 0 ) {
flags |= ESI->profile.flags;
}
/* make sure no invalid flags are set */
if ( flags &
~( PAPI_PROFIL_POSIX | PAPI_PROFIL_RANDOM | PAPI_PROFIL_WEIGHTED |
PAPI_PROFIL_COMPRESS | PAPI_PROFIL_BUCKETS | PAPI_PROFIL_FORCE_SW |
PAPI_PROFIL_INST_EAR | PAPI_PROFIL_DATA_EAR ) ) {
papi_return( PAPI_EINVAL );
}
/* if we have kernel-based profiling, then we're just asking for
signals on interrupt. */
/* if we don't have kernel-based profiling, then we're asking for
emulated PMU interrupt */
if ( ( flags & PAPI_PROFIL_FORCE_SW ) &&
( _papi_hwd[cidx]->cmp_info.kernel_profile == 0 ) ) {
forceSW = PAPI_OVERFLOW_FORCE_SW;
}
/* make sure one and only one bucket size is set */
buckets = flags & PAPI_PROFIL_BUCKETS;
if ( !buckets ) {
flags |= PAPI_PROFIL_BUCKET_16; /* default to 16 bit if nothing set */
}
else {
/* return error if more than one set */
if ( !( ( buckets == PAPI_PROFIL_BUCKET_16 ) ||
( buckets == PAPI_PROFIL_BUCKET_32 ) ||
( buckets == PAPI_PROFIL_BUCKET_64 ) ) ) {
papi_return( PAPI_EINVAL );
}
}
/* Set up the option structure for the low level */
ESI->profile.flags = flags;
if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
!( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
retval = _papi_hwd[cidx]->set_profile( ESI, index, threshold );
if ( ( retval == PAPI_OK ) && ( threshold > 0 ) ) {
/* We need overflowing because we use the overflow dispatch handler */
ESI->state |= PAPI_OVERFLOWING;
ESI->overflow.flags |= PAPI_OVERFLOW_HARDWARE;
}
} else {
retval = PAPI_overflow( EventSet, EventCode, threshold, forceSW,
_papi_hwi_dummy_handler );
}
if ( retval < PAPI_OK ) {
papi_return( retval ); /* We should undo stuff here */
}
/* Toggle the profiling flags and ESI state */
if ( ESI->profile.event_counter >= 1 ) {
ESI->state |= PAPI_PROFILING;
}
else {
ESI->state ^= PAPI_PROFILING;
ESI->profile.flags = 0;
}
return PAPI_OK;
}
| int PAPI_start | ( | int | EventSet | ) |
start counting hardware events in an event set
Definition at line 2034 of file papi.c.
{
APIDBG("Entry: EventSet: %d\n", EventSet);
int is_dirty=0;
int retval;
EventSetInfo_t *ESI;
ThreadInfo_t *thread = NULL;
CpuInfo_t *cpu = NULL;
hwd_context_t *context;
int cidx;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL ) {
papi_return( PAPI_ENOEVST );
}
cidx = valid_ESI_component( ESI );
if ( cidx < 0 ) {
papi_return( cidx );
}
/* only one event set per thread/cpu can be running at any time, */
/* so if another event set is running, the user must stop that */
/* event set explicitly */
thread = ESI->master;
cpu = ESI->CpuInfo;
/* check cpu attached case first */
if (ESI->state & PAPI_CPU_ATTACHED) {
if ( cpu->running_eventset[cidx] ) {
papi_return( PAPI_EISRUN );
}
} else {
if ( thread->running_eventset[cidx] ) {
papi_return( PAPI_EISRUN );
}
}
/* Check that there are added events */
if ( ESI->NumberOfEvents < 1 ) {
papi_return( PAPI_EINVAL );
}
/* If multiplexing is enabled for this eventset,
call John May's code. */
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
retval = MPX_start( ESI->multiplex.mpx_evset );
if ( retval != PAPI_OK ) {
papi_return( retval );
}
/* Update the state of this EventSet */
ESI->state ^= PAPI_STOPPED;
ESI->state |= PAPI_RUNNING;
return PAPI_OK;
}
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, &is_dirty );
if (is_dirty) {
/* we need to reset the context state because it was last used */
/* for some other event set and does not contain the information */
/* for our events. */
retval = _papi_hwd[ESI->CmpIdx]->update_control_state(
ESI->ctl_state,
ESI->NativeInfoArray,
ESI->NativeCount,
context);
if ( retval != PAPI_OK ) {
papi_return( retval );
}
/* now that the context contains this event sets information, */
/* make sure the position array in the EventInfoArray is correct */
/* We have to do this because ->update_control_state() can */
/* in theory re-order the native events out from under us. */
_papi_hwi_map_events_to_native( ESI );
}
/* If overflowing is enabled, turn it on */
if ( ( ESI->state & PAPI_OVERFLOWING ) &&
!( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
retval = _papi_hwi_start_signal( _papi_os_info.itimer_sig,
NEED_CONTEXT, cidx );
if ( retval != PAPI_OK ) {
papi_return( retval );
}
/* Update the state of this EventSet and thread */
/* before to avoid races */
ESI->state ^= PAPI_STOPPED;
ESI->state |= PAPI_RUNNING;
/* can not be attached to thread or cpu if overflowing */
thread->running_eventset[cidx] = ESI;
retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
if ( retval != PAPI_OK ) {
_papi_hwi_stop_signal( _papi_os_info.itimer_sig );
ESI->state ^= PAPI_RUNNING;
ESI->state |= PAPI_STOPPED;
thread->running_eventset[cidx] = NULL;
papi_return( retval );
}
retval = _papi_hwi_start_timer( _papi_os_info.itimer_num,
_papi_os_info.itimer_sig,
_papi_os_info.itimer_ns );
if ( retval != PAPI_OK ) {
_papi_hwi_stop_signal( _papi_os_info.itimer_sig );
_papi_hwd[cidx]->stop( context, ESI->ctl_state );
ESI->state ^= PAPI_RUNNING;
ESI->state |= PAPI_STOPPED;
thread->running_eventset[cidx] = NULL;
papi_return( retval );
}
} else {
/* Update the state of this EventSet and thread before */
/* to avoid races */
ESI->state ^= PAPI_STOPPED;
ESI->state |= PAPI_RUNNING;
/* if not attached to cpu or another process */
if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
if ( !( ESI->state & PAPI_ATTACHED ) ) {
thread->running_eventset[cidx] = ESI;
}
} else {
cpu->running_eventset[cidx] = ESI;
}
retval = _papi_hwd[cidx]->start( context, ESI->ctl_state );
if ( retval != PAPI_OK ) {
_papi_hwd[cidx]->stop( context, ESI->ctl_state );
ESI->state ^= PAPI_RUNNING;
ESI->state |= PAPI_STOPPED;
if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
if ( !( ESI->state & PAPI_ATTACHED ) )
thread->running_eventset[cidx] = NULL;
} else {
cpu->running_eventset[cidx] = NULL;
}
papi_return( retval );
}
}
return retval;
}
| int PAPI_state | ( | int | EventSet, |
| int * | status | ||
| ) |
return the counting state of an event set
Definition at line 2976 of file papi.c.
{
EventSetInfo_t *ESI;
if ( status == NULL )
papi_return( PAPI_EINVAL );
/* check for good EventSetIndex value */
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
/*read status FROM ESI->state */
*status = ESI->state;
return ( PAPI_OK );
}
| int PAPI_stop | ( | int | EventSet, |
| long long * | values | ||
| ) |
stop counting hardware events in an event set and return current events
Definition at line 2239 of file papi.c.
{
APIDBG("Entry: EventSet: %d, values: %p\n", EventSet, values);
EventSetInfo_t *ESI;
hwd_context_t *context;
int cidx, retval;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( !( ESI->state & PAPI_RUNNING ) )
papi_return( PAPI_ENOTRUN );
/* If multiplexing is enabled for this eventset, turn if off */
if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
retval = MPX_stop( ESI->multiplex.mpx_evset, values );
if ( retval != PAPI_OK )
papi_return( retval );
/* Update the state of this EventSet */
ESI->state ^= PAPI_RUNNING;
ESI->state |= PAPI_STOPPED;
return ( PAPI_OK );
}
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, NULL );
/* Read the current counter values into the EventSet */
retval = _papi_hwi_read( context, ESI, ESI->sw_stop );
if ( retval != PAPI_OK )
papi_return( retval );
/* Remove the control bits from the active counter config. */
retval = _papi_hwd[cidx]->stop( context, ESI->ctl_state );
if ( retval != PAPI_OK )
papi_return( retval );
if ( values )
memcpy( values, ESI->sw_stop,
( size_t ) ESI->NumberOfEvents * sizeof ( long long ) );
/* If kernel profiling is in use, flush and process the kernel buffer */
if ( ESI->state & PAPI_PROFILING ) {
if ( _papi_hwd[cidx]->cmp_info.kernel_profile &&
!( ESI->profile.flags & PAPI_PROFIL_FORCE_SW ) ) {
retval = _papi_hwd[cidx]->stop_profiling( ESI->master, ESI );
if ( retval < PAPI_OK )
papi_return( retval );
}
}
/* If overflowing is enabled, turn it off */
if ( ESI->state & PAPI_OVERFLOWING ) {
if ( !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
retval = _papi_hwi_stop_timer( _papi_os_info.itimer_num,
_papi_os_info.itimer_sig );
if ( retval != PAPI_OK )
papi_return( retval );
_papi_hwi_stop_signal( _papi_os_info.itimer_sig );
}
}
/* Update the state of this EventSet */
ESI->state ^= PAPI_RUNNING;
ESI->state |= PAPI_STOPPED;
/* Update the running event set for this thread */
if ( !(ESI->state & PAPI_CPU_ATTACHED) ) {
if ( !( ESI->state & PAPI_ATTACHED ))
ESI->master->running_eventset[cidx] = NULL;
} else {
ESI->CpuInfo->running_eventset[cidx] = NULL;
}
#if defined(DEBUG)
if ( _papi_hwi_debug & DEBUG_API ) {
int i;
for ( i = 0; i < ESI->NumberOfEvents; i++ ) {
APIDBG( "PAPI_stop ESI->sw_stop[%d]:\t%llu\n", i, ESI->sw_stop[i] );
}
}
#endif
return ( PAPI_OK );
}
| char* PAPI_strerror | ( | int | ) |
return a pointer to the error name corresponding to a specified error code
Definition at line 4498 of file papi.c.
{
if ( ( errorCode > 0 ) || ( -errorCode > _papi_hwi_num_errors ) )
return ( NULL );
return ( _papi_errlist[-errorCode] );
}
| unsigned long PAPI_thread_id | ( | void | ) |
get the thread identifier of the current thread
Definition at line 156 of file papi.c.
{
if ( _papi_hwi_thread_id_fn != NULL )
return ( ( *_papi_hwi_thread_id_fn ) ( ) );
else
#ifdef DEBUG
if ( _papi_hwi_debug_handler )
return ( unsigned long ) _papi_hwi_debug_handler( PAPI_EMISC );
#endif
return ( unsigned long ) PAPI_EMISC;
}
| int PAPI_thread_init | ( | unsigned long(*)(void) | id_fn | ) |
initialize thread support in the PAPI library
| int PAPI_unlock | ( | int | ) |
unlock one of two PAPI internal user mutex variables
Definition at line 6299 of file papi.c.
{
if ( ( lck < 0 ) || ( lck >= PAPI_NUM_LOCK ) )
papi_return( PAPI_EINVAL );
papi_return( _papi_hwi_unlock( lck ) );
}
| int PAPI_unregister_thread | ( | void | ) |
inform PAPI that a previously registered thread is disappearing
Definition at line 240 of file papi.c.
{
ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
if ( thread )
papi_return( _papi_hwi_shutdown_thread( thread ) );
papi_return( PAPI_EMISC );
}
| int PAPI_write | ( | int | EventSet, |
| long long * | values | ||
| ) |
write counter values into counters
Definition at line 2738 of file papi.c.
{
int cidx, retval = PAPI_OK;
EventSetInfo_t *ESI;
hwd_context_t *context;
ESI = _papi_hwi_lookup_EventSet( EventSet );
if ( ESI == NULL )
papi_return( PAPI_ENOEVST );
cidx = valid_ESI_component( ESI );
if ( cidx < 0 )
papi_return( cidx );
if ( values == NULL )
papi_return( PAPI_EINVAL );
if ( ESI->state & PAPI_RUNNING ) {
/* get the context we should use for this event set */
context = _papi_hwi_get_context( ESI, NULL );
retval = _papi_hwd[cidx]->write( context, ESI->ctl_state, values );
if ( retval != PAPI_OK )
return ( retval );
}
memcpy( ESI->hw_start, values,
( size_t ) _papi_hwd[cidx]->cmp_info.num_cntrs *
sizeof ( long long ) );
return ( retval );
}