|
Packit |
577717 |
/****************************/
|
|
Packit |
577717 |
/* THIS IS OPEN SOURCE CODE */
|
|
Packit |
577717 |
/****************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* @file linux-IOunit.c
|
|
Packit |
577717 |
* @author Heike Jagode
|
|
Packit |
577717 |
* jagode@eecs.utk.edu
|
|
Packit |
577717 |
* Mods: < your name here >
|
|
Packit |
577717 |
* < your email address >
|
|
Packit |
577717 |
* BGPM / IOunit component
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Tested version of bgpm (early access)
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* @brief
|
|
Packit |
577717 |
* This file has the source code for a component that enables PAPI-C to
|
|
Packit |
577717 |
* access hardware monitoring counters for BG/Q through the bgpm library.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include "linux-IOunit.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Declare our vector in advance */
|
|
Packit |
577717 |
papi_vector_t _IOunit_vector;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* prototypes */
|
|
Packit |
577717 |
void user_signal_handler_IOUNIT( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*****************************************************************************
|
|
Packit |
577717 |
******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS *************
|
|
Packit |
577717 |
*****************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* This is called whenever a thread is initialized
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_init_thread( hwd_context_t * ctx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_init_thread\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Initialize hardware counters, setup the function vector table
|
|
Packit |
577717 |
* and get hardware information, this routine is called when the
|
|
Packit |
577717 |
* PAPI process is initialized (IE PAPI_library_init)
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_init_component( int cidx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_init_component\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_IOunit_vector.cmp_info.CmpIdx = cidx;
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_init_component cidx = %d\n", cidx );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Control of counters (Reading/Writing/Starting/Stopping/Setup)
|
|
Packit |
577717 |
* functions
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_init_control_state( hwd_control_state_t * ptr )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_init_control_state\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
this_state->EventGroup = Bgpm_CreateEventSet();
|
|
Packit |
577717 |
retval = _check_BGPM_error( this_state->EventGroup, "Bgpm_CreateEventSet" );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// initialize overflow flag to OFF (0)
|
|
Packit |
577717 |
this_state->overflow = 0;
|
|
Packit |
577717 |
this_state->overflow_count = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_start( hwd_context_t * ctx, hwd_control_state_t * ptr )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_start\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = Bgpm_ResetStart( this_state->EventGroup );
|
|
Packit |
577717 |
retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_stop( hwd_context_t * ctx, hwd_control_state_t * ptr )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_stop\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = Bgpm_Stop( this_state->EventGroup );
|
|
Packit |
577717 |
retval = _check_BGPM_error( retval, "Bgpm_Stop" );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_read( hwd_context_t * ctx, hwd_control_state_t * ptr,
|
|
Packit |
577717 |
long_long ** events, int flags )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_read\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
( void ) flags;
|
|
Packit |
577717 |
int i, numEvts;
|
|
Packit |
577717 |
IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
numEvts = Bgpm_NumEvents( this_state->EventGroup );
|
|
Packit |
577717 |
if ( numEvts == 0 ) {
|
|
Packit |
577717 |
#ifdef DEBUG_BGPM
|
|
Packit |
577717 |
printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
//return ( EXIT_FAILURE );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < numEvts; i++ )
|
|
Packit |
577717 |
this_state->counts[i] = _common_getEventValue( i, this_state->EventGroup );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
*events = this_state->counts;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_shutdown_thread( hwd_context_t * ctx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_shutdown_thread\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* user_signal_handler
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* This function is used when hardware overflows are working or when
|
|
Packit |
577717 |
* software overflows are forced
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
void
|
|
Packit |
577717 |
user_signal_handler_IOUNIT( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "user_signal_handler_IOUNIT\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
( void ) address;
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
unsigned i;
|
|
Packit |
577717 |
int isHardware = 1;
|
|
Packit |
577717 |
int cidx = _IOunit_vector.cmp_info.CmpIdx;
|
|
Packit |
577717 |
long_long overflow_bit = 0;
|
|
Packit |
577717 |
caddr_t address1;
|
|
Packit |
577717 |
_papi_hwi_context_t ctx;
|
|
Packit |
577717 |
ctx.ucontext = ( hwd_ucontext_t * ) pContext;
|
|
Packit |
577717 |
ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
|
|
Packit |
577717 |
EventSetInfo_t *ESI;
|
|
Packit |
577717 |
ESI = thread->running_eventset[cidx];
|
|
Packit |
577717 |
// Get the indices of all events which have overflowed.
|
|
Packit |
577717 |
unsigned ovfIdxs[BGPM_MAX_OVERFLOW_EVENTS];
|
|
Packit |
577717 |
unsigned len = BGPM_MAX_OVERFLOW_EVENTS;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = Bgpm_GetOverflowEventIndices( hEvtSet, ovfVector, ovfIdxs, &len );
|
|
Packit |
577717 |
if ( retval < 0 ) {
|
|
Packit |
577717 |
#ifdef DEBUG_BGPM
|
|
Packit |
577717 |
printf ( "Error: ret value is %d for BGPM API function Bgpm_GetOverflowEventIndices.\n",
|
|
Packit |
577717 |
retval );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( thread == NULL ) {
|
|
Packit |
577717 |
PAPIERROR( "thread == NULL in user_signal_handler!" );
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI == NULL ) {
|
|
Packit |
577717 |
PAPIERROR( "ESI == NULL in user_signal_handler!");
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->overflow.flags == 0 ) {
|
|
Packit |
577717 |
PAPIERROR( "ESI->overflow.flags == 0 in user_signal_handler!");
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < len; i++ ) {
|
|
Packit |
577717 |
uint64_t hProf;
|
|
Packit |
577717 |
Bgpm_GetEventUser1( hEvtSet, ovfIdxs[i], &hProf );
|
|
Packit |
577717 |
if ( hProf ) {
|
|
Packit |
577717 |
overflow_bit ^= 1 << ovfIdxs[i];
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) {
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf("OVERFLOW_SOFTWARE\n");
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
address1 = GET_OVERFLOW_ADDRESS( ctx );
|
|
Packit |
577717 |
_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, NULL, 0, 0, &thread, cidx );
|
|
Packit |
577717 |
return;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf("OVERFLOW_HARDWARE\n");
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
address1 = GET_OVERFLOW_ADDRESS( ctx );
|
|
Packit |
577717 |
_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, &isHardware, overflow_bit, 0, &thread, cidx );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf("OVERFLOW_NONE\n");
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
PAPIERROR( "ESI->overflow.flags is set to something other than PAPI_OVERFLOW_HARDWARE or PAPI_OVERFLOW_FORCE_SW (%#x)", thread->running_eventset[cidx]->overflow.flags);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Set Overflow
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* This is commented out in BG/L/P - need to explore and complete...
|
|
Packit |
577717 |
* However, with true 64-bit counters in BG/Q and all counters for PAPI
|
|
Packit |
577717 |
* always starting from a true zero (we don't allow write...), the possibility
|
|
Packit |
577717 |
* for overflow is remote at best...
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf("BEGIN IOUNIT_set_overflow\n");
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ESI->ctl_state;
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
int evt_idx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
|
|
Packit |
577717 |
SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
|
|
Packit |
577717 |
evt_idx, EventIndex, threshold );
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
|
|
Packit |
577717 |
evt_idx, EventIndex, threshold );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
/* If this counter isn't set to overflow, it's an error */
|
|
Packit |
577717 |
if ( threshold == 0 ) {
|
|
Packit |
577717 |
/* Remove the signal handler */
|
|
Packit |
577717 |
retval = _papi_hwi_stop_signal( _IOunit_vector.cmp_info.hardware_intr_sig );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
this_state->overflow = 1;
|
|
Packit |
577717 |
this_state->overflow_count++;
|
|
Packit |
577717 |
this_state->overflow_list[this_state->overflow_count-1].threshold = threshold;
|
|
Packit |
577717 |
this_state->overflow_list[this_state->overflow_count-1].EventIndex = evt_idx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_set_overflow: Enable the signal handler\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
/* Enable the signal handler */
|
|
Packit |
577717 |
retval = _papi_hwi_start_signal( _IOunit_vector.cmp_info.hardware_intr_sig,
|
|
Packit |
577717 |
NEED_CONTEXT,
|
|
Packit |
577717 |
_IOunit_vector.cmp_info.CmpIdx );
|
|
Packit |
577717 |
if ( retval != PAPI_OK )
|
|
Packit |
577717 |
return ( retval );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = _common_set_overflow_BGPM( this_state->EventGroup,
|
|
Packit |
577717 |
this_state->overflow_list[this_state->overflow_count-1].EventIndex,
|
|
Packit |
577717 |
this_state->overflow_list[this_state->overflow_count-1].threshold,
|
|
Packit |
577717 |
user_signal_handler_IOUNIT );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This function sets various options in the component
|
|
Packit |
577717 |
* The valid codes being passed in are PAPI_SET_DEFDOM,
|
|
Packit |
577717 |
* PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_ctl\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
( void ) code;
|
|
Packit |
577717 |
( void ) option;
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_update_control_state( hwd_control_state_t * ptr,
|
|
Packit |
577717 |
NativeInfo_t * native, int count,
|
|
Packit |
577717 |
hwd_context_t * ctx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_update_control_state: count = %d\n", count );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
int retval, index, i, k;
|
|
Packit |
577717 |
IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// Delete and re-create BGPM eventset
|
|
Packit |
577717 |
retval = _common_deleteRecreate( &this_state->EventGroup );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_update_control_state: EventGroup=%d, overflow = %d\n",
|
|
Packit |
577717 |
this_state->EventGroup, this_state->overflow );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// otherwise, add the events to the eventset
|
|
Packit |
577717 |
for ( i = 0; i < count; i++ ) {
|
|
Packit |
577717 |
index = ( native[i].ni_event ) + OFFSET;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
native[i].ni_position = i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf("IOUNIT_update_control_state: ADD event: i = %d, index = %d\n", i, index );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Add events to the BGPM eventGroup */
|
|
Packit |
577717 |
retval = Bgpm_AddEvent( this_state->EventGroup, index );
|
|
Packit |
577717 |
retval = _check_BGPM_error( retval, "Bgpm_AddEvent" );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// since update_control_state trashes overflow settings, this puts things
|
|
Packit |
577717 |
// back into balance for BGPM
|
|
Packit |
577717 |
if ( 1 == this_state->overflow ) {
|
|
Packit |
577717 |
for ( k = 0; k < this_state->overflow_count; k++ ) {
|
|
Packit |
577717 |
retval = _common_set_overflow_BGPM( this_state->EventGroup,
|
|
Packit |
577717 |
this_state->overflow_list[k].EventIndex,
|
|
Packit |
577717 |
this_state->overflow_list[k].threshold,
|
|
Packit |
577717 |
user_signal_handler_IOUNIT );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* This function has to set the bits needed to count different domains
|
|
Packit |
577717 |
* In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
|
|
Packit |
577717 |
* By default return PAPI_EINVAL if none of those are specified
|
|
Packit |
577717 |
* and PAPI_OK with success
|
|
Packit |
577717 |
* PAPI_DOM_USER is only user context is counted
|
|
Packit |
577717 |
* PAPI_DOM_KERNEL is only the Kernel/OS context is counted
|
|
Packit |
577717 |
* PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
|
|
Packit |
577717 |
* PAPI_DOM_ALL is all of the domains
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_set_domain( hwd_control_state_t * cntrl, int domain )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_set_domain\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
int found = 0;
|
|
Packit |
577717 |
( void ) cntrl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( PAPI_DOM_USER & domain )
|
|
Packit |
577717 |
found = 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( PAPI_DOM_KERNEL & domain )
|
|
Packit |
577717 |
found = 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( PAPI_DOM_OTHER & domain )
|
|
Packit |
577717 |
found = 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( !found )
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_reset( hwd_context_t * ctx, hwd_control_state_t * ptr )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_reset\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* we can't simply call Bgpm_Reset() since PAPI doesn't have the
|
|
Packit |
577717 |
restriction that an EventSet has to be stopped before resetting is
|
|
Packit |
577717 |
possible. However, BGPM does have this restriction.
|
|
Packit |
577717 |
Hence we need to stop, reset and start */
|
|
Packit |
577717 |
retval = Bgpm_Stop( this_state->EventGroup );
|
|
Packit |
577717 |
retval = _check_BGPM_error( retval, "Bgpm_Stop" );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = Bgpm_ResetStart( this_state->EventGroup );
|
|
Packit |
577717 |
retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* PAPI Cleanup Eventset
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* Destroy and re-create the BGPM / IOunit EventSet
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_cleanup_eventset( hwd_control_state_t * ctrl )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_cleanup_eventset\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
int retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ctrl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// create a new empty bgpm eventset
|
|
Packit |
577717 |
// reason: bgpm doesn't permit to remove events from an eventset;
|
|
Packit |
577717 |
// hence we delete the old eventset and create a new one
|
|
Packit |
577717 |
retval = _common_deleteRecreate( &this_state->EventGroup ); // HJ try to use delete() only
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// set overflow flag to OFF (0)
|
|
Packit |
577717 |
this_state->overflow = 0;
|
|
Packit |
577717 |
this_state->overflow_count = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Native Event functions
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_ntv_enum_events( unsigned int *EventCode, int modifier )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
//printf( "IOUNIT_ntv_enum_events\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch ( modifier ) {
|
|
Packit |
577717 |
case PAPI_ENUM_FIRST:
|
|
Packit |
577717 |
*EventCode = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PAPI_ENUM_EVENTS:
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int index = ( *EventCode ) + OFFSET;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( index < IOUNIT_MAX_EVENTS ) {
|
|
Packit |
577717 |
*EventCode = *EventCode + 1;
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
} else
|
|
Packit |
577717 |
return ( PAPI_ENOEVNT );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
break;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return ( PAPI_EINVAL );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_ntv_name_to_code( const char *name, unsigned int *event_code )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_ntv_name_to_code\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
int ret;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Return event id matching a given event label string */
|
|
Packit |
577717 |
ret = Bgpm_GetEventIdFromLabel ( name );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ret <= 0 ) {
|
|
Packit |
577717 |
#ifdef DEBUG_BGPM
|
|
Packit |
577717 |
printf ("Error: ret value is %d for BGPM API function '%s'.\n",
|
|
Packit |
577717 |
ret, "Bgpm_GetEventIdFromLabel" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else if ( ret < OFFSET || ret > IOUNIT_MAX_EVENTS ) // not an IOUnit event
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
else
|
|
Packit |
577717 |
*event_code = ( ret - OFFSET ) ;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_ntv_code_to_name( unsigned int EventCode, char *name, int len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
//printf( "IOUNIT_ntv_code_to_name\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
int index;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
index = ( EventCode ) + OFFSET;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( index >= MAX_COUNTERS )
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
strncpy( name, Bgpm_GetEventIdLabel( index ), len );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( name == NULL ) {
|
|
Packit |
577717 |
#ifdef DEBUG_BGPM
|
|
Packit |
577717 |
printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
//printf( "IOUNIT_ntv_code_to_descr\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
int retval, index;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
index = ( EventCode ) + OFFSET;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
retval = Bgpm_GetLongDesc( index, name, &len );
|
|
Packit |
577717 |
retval = _check_BGPM_error( retval, "Bgpm_GetLongDesc" );
|
|
Packit |
577717 |
if ( retval < 0 ) return retval;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
int
|
|
Packit |
577717 |
IOUNIT_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
#ifdef DEBUG_BGQ
|
|
Packit |
577717 |
printf( "IOUNIT_ntv_code_to_bits\n" );
|
|
Packit |
577717 |
#endif
|
|
Packit |
577717 |
( void ) EventCode;
|
|
Packit |
577717 |
( void ) bits;
|
|
Packit |
577717 |
return ( PAPI_OK );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
papi_vector_t _IOunit_vector = {
|
|
Packit |
577717 |
.cmp_info = {
|
|
Packit |
577717 |
/* default component information (unspecified values are initialized to 0) */
|
|
Packit |
577717 |
.name = "bgpm/IOUnit",
|
|
Packit |
577717 |
.short_name = "IOUnit",
|
|
Packit |
577717 |
.description = "Blue Gene/Q IOUnit component",
|
|
Packit |
577717 |
.num_native_events = IOUNIT_MAX_EVENTS-OFFSET+1,
|
|
Packit |
577717 |
.num_cntrs = IOUNIT_MAX_COUNTERS,
|
|
Packit |
577717 |
.num_mpx_cntrs = IOUNIT_MAX_COUNTERS,
|
|
Packit |
577717 |
.default_domain = PAPI_DOM_USER,
|
|
Packit |
577717 |
.available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
|
|
Packit |
577717 |
.default_granularity = PAPI_GRN_THR,
|
|
Packit |
577717 |
.available_granularities = PAPI_GRN_THR,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.hardware_intr_sig = PAPI_INT_SIGNAL,
|
|
Packit |
577717 |
.hardware_intr = 1,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.kernel_multiplex = 0,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* component specific cmp_info initializations */
|
|
Packit |
577717 |
.fast_real_timer = 0,
|
|
Packit |
577717 |
.fast_virtual_timer = 0,
|
|
Packit |
577717 |
.attach = 0,
|
|
Packit |
577717 |
.attach_must_ptrace = 0,
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* sizes of framework-opaque component-private structures */
|
|
Packit |
577717 |
.size = {
|
|
Packit |
577717 |
.context = sizeof ( IOUNIT_context_t ),
|
|
Packit |
577717 |
.control_state = sizeof ( IOUNIT_control_state_t ),
|
|
Packit |
577717 |
.reg_value = sizeof ( IOUNIT_register_t ),
|
|
Packit |
577717 |
.reg_alloc = sizeof ( IOUNIT_reg_alloc_t ),
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
,
|
|
Packit |
577717 |
/* function pointers in this component */
|
|
Packit |
577717 |
.init_thread = IOUNIT_init_thread,
|
|
Packit |
577717 |
.init_component = IOUNIT_init_component,
|
|
Packit |
577717 |
.init_control_state = IOUNIT_init_control_state,
|
|
Packit |
577717 |
.start = IOUNIT_start,
|
|
Packit |
577717 |
.stop = IOUNIT_stop,
|
|
Packit |
577717 |
.read = IOUNIT_read,
|
|
Packit |
577717 |
.shutdown_thread = IOUNIT_shutdown_thread,
|
|
Packit |
577717 |
.set_overflow = IOUNIT_set_overflow,
|
|
Packit |
577717 |
.cleanup_eventset = IOUNIT_cleanup_eventset,
|
|
Packit |
577717 |
.ctl = IOUNIT_ctl,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.update_control_state = IOUNIT_update_control_state,
|
|
Packit |
577717 |
.set_domain = IOUNIT_set_domain,
|
|
Packit |
577717 |
.reset = IOUNIT_reset,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.ntv_name_to_code = IOUNIT_ntv_name_to_code,
|
|
Packit |
577717 |
.ntv_enum_events = IOUNIT_ntv_enum_events,
|
|
Packit |
577717 |
.ntv_code_to_name = IOUNIT_ntv_code_to_name,
|
|
Packit |
577717 |
.ntv_code_to_descr = IOUNIT_ntv_code_to_descr,
|
|
Packit |
577717 |
.ntv_code_to_bits = IOUNIT_ntv_code_to_bits
|
|
Packit |
577717 |
};
|