Blame src/components/bgpm/IOunit/linux-IOunit.c

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