Blame src/linux-bgp.c

Packit 577717
/*
Packit 577717
 * File:    linux-bgp.c
Packit 577717
 * Author:  Dave Hermsmeier
Packit 577717
 *          dlherms@us.ibm.com
Packit 577717
 */
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI stuff
Packit 577717
 */
Packit 577717
#include "papi.h"
Packit 577717
#include "papi_internal.h"
Packit 577717
#include "papi_vector.h"
Packit 577717
#include "papi_memory.h"
Packit 577717
#include "extras.h"
Packit 577717
Packit 577717
#include "linux-bgp.h"
Packit 577717
/*
Packit 577717
 * BG/P specific 'stuff'
Packit 577717
 */
Packit 577717
Packit 577717
/* BG/P includes */
Packit 577717
#include <common/bgp_personality_inlines.h>
Packit 577717
#include <spi/bgp_SPI.h>
Packit 577717
#include <ucontext.h>
Packit 577717
#include <stdlib.h>
Packit 577717
#include <signal.h>
Packit 577717
#include <sys/time.h>
Packit 577717
#include <errno.h>
Packit 577717
#include <stdio.h>
Packit 577717
#include <string.h>
Packit 577717
#include <sys/utsname.h>
Packit 577717
Packit 577717
/* BG/P macros */
Packit 577717
#define get_cycles _bgp_GetTimeBase
Packit 577717
Packit 577717
/* BG/P external structures/functions */
Packit 577717
Packit 577717
papi_vector_t _bgp_vectors;
Packit 577717
Packit 577717
/* Defined in linux-bgp-memory.c */
Packit 577717
extern int _bgp_get_memory_info( PAPI_hw_info_t * pHwInfo, int pCPU_Type );
Packit 577717
extern int _bgp_get_dmem_info( PAPI_dmem_info_t * pDmemInfo );
Packit 577717
Packit 577717
/* BG/P globals */
Packit 577717
hwi_search_t *preset_search_map;
Packit 577717
volatile unsigned int lock[PAPI_MAX_LOCK];
Packit 577717
const char *BGP_NATIVE_RESERVED_EVENTID = "Reserved";
Packit 577717
PAPI_os_info_t _papi_os_info;
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Get BGP Native Event Id from PAPI Event Id
Packit 577717
 */
Packit 577717
inline BGP_UPC_Event_Id_t
Packit 577717
get_bgp_native_event_id( int pEventId )
Packit 577717
{
Packit 577717
	return ( BGP_UPC_Event_Id_t ) ( pEventId & PAPI_NATIVE_AND_MASK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Lock initialization
Packit 577717
 */
Packit 577717
void
Packit 577717
_papi_hwd_lock_init( void )
Packit 577717
{
Packit 577717
	/* PAPI on BG/P does not need locks. */
Packit 577717
Packit 577717
	return;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Lock
Packit 577717
 */
Packit 577717
void
Packit 577717
_papi_hwd_lock( int lock )
Packit 577717
{
Packit 577717
	/* PAPI on BG/P does not need locks. */
Packit 577717
Packit 577717
	return;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Unlock
Packit 577717
 */
Packit 577717
void
Packit 577717
_papi_hwd_unlock( int lock )
Packit 577717
{
Packit 577717
	/* PAPI on BG/P does not need locks. */
Packit 577717
Packit 577717
	return;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Get System Information
Packit 577717
 *
Packit 577717
 * Initialize system information structure
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_get_system_info( papi_mdi_t *mdi )
Packit 577717
{
Packit 577717
	_BGP_Personality_t bgp;
Packit 577717
	int tmp;
Packit 577717
	unsigned utmp;
Packit 577717
	char chipID[64];
Packit 577717
Packit 577717
	/* Hardware info */
Packit 577717
	if ( ( tmp = Kernel_GetPersonality( &bgp, sizeof bgp ) ) ) {
Packit 577717
Packit 577717
#include "error.h"
Packit 577717
Packit 577717
		fprintf( stdout, "Kernel_GetPersonality returned %d (sys error=%d).\n"
Packit 577717
				 "\t%s\n", tmp, errno, strerror( errno ) );
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.ncpu = Kernel_ProcessorCount(  );
Packit 577717
	_papi_hwi_system_info.hw_info.nnodes =
Packit 577717
		( int ) BGP_Personality_numComputeNodes( &bgp );
Packit 577717
	_papi_hwi_system_info.hw_info.totalcpus =
Packit 577717
		_papi_hwi_system_info.hw_info.ncpu *
Packit 577717
		_papi_hwi_system_info.hw_info.nnodes;
Packit 577717
Packit 577717
	utmp = Kernel_GetProcessorVersion(  );
Packit 577717
	_papi_hwi_system_info.hw_info.model = ( int ) utmp;
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.vendor = ( utmp >> ( 31 - 11 ) ) & 0xFFF;
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.revision =
Packit 577717
		( ( float ) ( ( utmp >> ( 31 - 15 ) ) & 0xFFFF ) ) +
Packit 577717
		0.00001 * ( ( float ) ( utmp & 0xFFFF ) );
Packit 577717
Packit 577717
	strcpy( _papi_hwi_system_info.hw_info.vendor_string, "IBM" );
Packit 577717
	tmp = snprintf( _papi_hwi_system_info.hw_info.model_string,
Packit 577717
					sizeof _papi_hwi_system_info.hw_info.model_string,
Packit 577717
					"PVR=%#4.4x:%#4.4x",
Packit 577717
					( utmp >> ( 31 - 15 ) ) & 0xFFFF, ( utmp & 0xFFFF ) );
Packit 577717
Packit 577717
	BGP_Personality_getLocationString( &bgp, chipID );
Packit 577717
	tmp += 12 + sizeof ( chipID );
Packit 577717
	if ( sizeof ( _papi_hwi_system_info.hw_info.model_string ) > tmp ) {
Packit 577717
		strcat( _papi_hwi_system_info.hw_info.model_string, "  Serial=" );
Packit 577717
		strncat( _papi_hwi_system_info.hw_info.model_string,
Packit 577717
				 chipID, sizeof ( chipID ) );
Packit 577717
	}
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.mhz =
Packit 577717
		( float ) BGP_Personality_clockMHz( &bgp );
Packit 577717
	SUBDBG( "_bgp_get_system_info:  Detected MHZ is %f\n",
Packit 577717
			_papi_hwi_system_info.hw_info.mhz );
Packit 577717
Packit 577717
	_papi_hwi_system_info.hw_info.cpu_max_mhz=_papi_hwi_system_info.hw_info.mhz;
Packit 577717
	_papi_hwi_system_info.hw_info.cpu_min_mhz=_papi_hwi_system_info.hw_info.mhz;
Packit 577717
Packit 577717
	// Memory information structure not filled in - same as BG/L
Packit 577717
	// _papi_hwi_system_info.hw_info.mem_hierarchy = ???;
Packit 577717
	// The mpx_info structure disappeared in PAPI-C
Packit 577717
	//_papi_hwi_system_info.mpx_info.timer_sig = PAPI_NULL;
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Initialize Control State
Packit 577717
 *
Packit 577717
 * All state is kept in BG/P UPC structures
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_init_control_state( hwd_control_state_t *ctl )
Packit 577717
{
Packit 577717
	int i;
Packit 577717
Packit 577717
	//bgp_control_state_t *bgp_ctl = (bgp_control_state_t *)ctl;
Packit 577717
Packit 577717
	for ( i = 1; i < BGP_UPC_MAX_MONITORED_EVENTS; i++ )
Packit 577717
		ctl->counters[i] = 0;
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Set Domain
Packit 577717
 *
Packit 577717
 * All state is kept in BG/P UPC structures
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_set_domain( hwd_control_state_t * cntrl, int domain )
Packit 577717
{
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Initialization
Packit 577717
 *
Packit 577717
 * All state is kept in BG/P UPC structures
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_init_thread( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Global Initialization
Packit 577717
 *
Packit 577717
 * Global initialization - does initial PAPI setup and
Packit 577717
 *                         calls BGP_UPC_Initialize()
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_init_global( void )
Packit 577717
{
Packit 577717
	int retval;
Packit 577717
	int cidx = _bgp_vectors.cmp_info.CmpIdx;
Packit 577717
	
Packit 577717
	/*
Packit 577717
	 * Fill in what we can of the papi_system_info
Packit 577717
	 */
Packit 577717
	SUBDBG( "Before _bgp_get_system_info()...\n" );
Packit 577717
	retval = _bgp_get_system_info( &_papi_hwi_system_info );
Packit 577717
	SUBDBG( "After _bgp_get_system_info(), retval=%d...\n", retval );
Packit 577717
	if ( retval != PAPI_OK )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	/*
Packit 577717
	 * Setup presets
Packit 577717
	 */
Packit 577717
	SUBDBG( "Before setup_bgp_presets, _papi_hwi_system_info.hw_info.model=%d...\n",
Packit 577717
		  _papi_hwi_system_info.hw_info.model );
Packit 577717
	retval = _papi_load_preset_table( "BGP", 0, cidx );
Packit 577717
	SUBDBG( "After setup_bgp_presets, retval=%d...\n", retval );
Packit 577717
	if ( retval )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	/*
Packit 577717
	 * Setup memory info
Packit 577717
	 */
Packit 577717
	SUBDBG( "Before _bgp_get_memory_info...\n" );
Packit 577717
	retval = _bgp_get_memory_info( &_papi_hwi_system_info.hw_info,
Packit 577717
								   ( int ) _papi_hwi_system_info.hw_info.
Packit 577717
								   model );
Packit 577717
	SUBDBG( "After _bgp_get_memory_info, retval=%d...\n", retval );
Packit 577717
	if ( retval )
Packit 577717
		return ( retval );
Packit 577717
Packit 577717
	/*
Packit 577717
	 * Initialize BG/P global variables...
Packit 577717
	 * NOTE:  If the BG/P SPI interface is to be used, then this
Packit 577717
	 *        initialize routine must be called from each process for the
Packit 577717
	 *        application.  It does not matter if this routine is called more
Packit 577717
	 *        than once per process, but must be called by each process at
Packit 577717
	 *        least once, preferably at the beginning of the application.
Packit 577717
	 */
Packit 577717
	SUBDBG( "Before BGP_UPC_Initialize()...\n" );
Packit 577717
	BGP_UPC_Initialize(  );
Packit 577717
	SUBDBG( "After BGP_UPC_Initialize()...\n" );
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Shutdown Global
Packit 577717
 *
Packit 577717
 * Called once per process - nothing to do
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_shutdown_global( void )
Packit 577717
{
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Register Allocation
Packit 577717
 *
Packit 577717
 * Sets up the UPC configuration to monitor those events
Packit 577717
 * as identified in the event set.
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_allocate_registers( EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
	int i, natNum;
Packit 577717
	BGP_UPC_Event_Id_t xEventId;
Packit 577717
Packit 577717
	/*
Packit 577717
	 * If an active UPC unit, return error
Packit 577717
	 */
Packit 577717
	if ( BGP_UPC_Check_Active(  ) ) {
Packit 577717
		SUBDBG( "_bgp_allocate_registers:  UPC is active...\n" );
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
Packit 577717
	/*
Packit 577717
	 * If a counter mode of 1, return error
Packit 577717
	 */
Packit 577717
	if ( BGP_UPC_Get_Counter_Mode(  ) ) {
Packit 577717
		SUBDBG( "_bgp_allocate_registers:  Inconsistent counter mode...\n" );
Packit 577717
		return PAPI_ESYS;
Packit 577717
	}
Packit 577717
Packit 577717
	/*
Packit 577717
	 * Start monitoring the events...
Packit 577717
	 */
Packit 577717
	natNum = ESI->NativeCount;
Packit 577717
//  printf("_bgp_allocate_registers:  natNum=%d\n", natNum);
Packit 577717
	for ( i = 0; i < natNum; i++ ) {
Packit 577717
		xEventId = get_bgp_native_event_id( ESI->NativeInfoArray[i].ni_event );
Packit 577717
//    printf("_bgp_allocate_registers:  xEventId = %d\n", xEventId);
Packit 577717
		if ( !BGP_UPC_Check_Active_Event( xEventId ) ) {
Packit 577717
			// NOTE:  We do not have to start monitoring for elapsed time...  It is always being
Packit 577717
			//        monitored at location 255...
Packit 577717
			if ( ( xEventId % BGP_UPC_MAX_MONITORED_EVENTS ) != 255 ) {
Packit 577717
				/*
Packit 577717
				 * The event is not already being monitored by the UPC, start monitoring
Packit 577717
				 * for the event.  This will automatically zero the counter and turn off any
Packit 577717
				 * threshold value...
Packit 577717
				 */
Packit 577717
//        printf("_bgp_allocate_registers:  Event id %d not being monitored...\n", xEventId);
Packit 577717
				if ( BGP_UPC_Monitor_Event( xEventId, BGP_UPC_CFG_EDGE_DEFAULT )
Packit 577717
					 < 0 ) {
Packit 577717
//          printf("_bgp_allocate_registers:  Monitor_Event failed...\n");
Packit 577717
					return PAPI_ECMP;
Packit 577717
				}
Packit 577717
			}
Packit 577717
                        /* here is if we are event 255 */ 
Packit 577717
			else {
Packit 577717
Packit 577717
			}
Packit 577717
Packit 577717
		} else {
Packit 577717
			/*
Packit 577717
			 * The event is already being monitored by the UPC.  This is a normal
Packit 577717
			 * case where the UPC is monitoring all events for a particular user
Packit 577717
			 * mode.  We are in this leg because the PAPI event set has not yet
Packit 577717
			 * started monitoring the event.  So, simply zero the counter and turn
Packit 577717
			 * off any threshold value...
Packit 577717
			 */
Packit 577717
//      printf("_bgp_allocate_registers:  Event id %d is already being monitored...\n", xEventId);
Packit 577717
			// NOTE:  Can't zero the counter or reset the threshold for the timestamp counter...
Packit 577717
			if ( ESI->NativeInfoArray[i].ni_event != PNE_BGP_IC_TIMESTAMP ) {
Packit 577717
				if ( BGP_UPC_Zero_Counter_Value( xEventId ) < 0 ) {
Packit 577717
//          printf("_bgp_allocate_registers:  Zero_Counter failed...\n");
Packit 577717
					return PAPI_ECMP;
Packit 577717
				}
Packit 577717
				if ( BGP_UPC_Set_Counter_Threshold_Value( xEventId, 0 ) < 0 ) {
Packit 577717
//          printf("_bgp_allocate_registers:  Set_Counter_Threshold_Value failed...\n");
Packit 577717
					return PAPI_ECMP;
Packit 577717
				}
Packit 577717
			}
Packit 577717
		}
Packit 577717
		ESI->NativeInfoArray[i].ni_position =
Packit 577717
			xEventId % BGP_UPC_MAX_MONITORED_EVENTS;
Packit 577717
//    printf("_bgp_allocate_registers:  ESI->NativeInfoArray[i].ni_position=%d\n", ESI->NativeInfoArray[i].ni_position);
Packit 577717
	}
Packit 577717
Packit 577717
//  printf("_bgp_allocate_registers:  Exiting normally...\n");
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Update Control State
Packit 577717
 *
Packit 577717
 * This function clears the current contents of the control
Packit 577717
 * structure and updates it with whatever resources are allocated
Packit 577717
 * for all the native events in the native info structure array.
Packit 577717
 *
Packit 577717
 * Since no BGP specific state is kept at the PAPI level, there is
Packit 577717
 * nothing to update and we simply return.
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_update_control_state( hwd_control_state_t *ctl,
Packit 577717
			   NativeInfo_t *native, int count,
Packit 577717
			   hwd_context_t *ctx )
Packit 577717
{
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/* Hack to get cycle count */
Packit 577717
static long_long begin_cycles;
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Start
Packit 577717
 *
Packit 577717
 * Start UPC unit(s)
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_start( hwd_context_t * ctx, hwd_control_state_t * ctrlstate )
Packit 577717
{
Packit 577717
	sigset_t mask_set;
Packit 577717
	sigset_t old_set;
Packit 577717
	sigemptyset( &mask_set );
Packit 577717
	sigaddset( &mask_set, SIGXCPU );
Packit 577717
	sigprocmask( SIG_BLOCK, &mask_set, &old_set );
Packit 577717
        begin_cycles=_bgp_GetTimeBase();
Packit 577717
	BGP_UPC_Start( BGP_UPC_NO_RESET_COUNTERS );
Packit 577717
	sigprocmask( SIG_UNBLOCK, &mask_set, NULL );
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Stop
Packit 577717
 *
Packit 577717
 * Stop UPC unit(s)
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_stop( hwd_context_t * ctx, hwd_control_state_t * state )
Packit 577717
{
Packit 577717
	sigset_t mask_set;
Packit 577717
	sigset_t old_set;
Packit 577717
	sigemptyset( &mask_set );
Packit 577717
	sigaddset( &mask_set, SIGXCPU );
Packit 577717
	sigprocmask( SIG_BLOCK, &mask_set, &old_set );
Packit 577717
	BGP_UPC_Stop(  );
Packit 577717
	sigprocmask( SIG_UNBLOCK, &mask_set, NULL );
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Read Counters
Packit 577717
 *
Packit 577717
 * Read the counters into local storage
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_read( hwd_context_t *ctx, hwd_control_state_t *ctl,
Packit 577717
		   long_long ** dp, int flags )
Packit 577717
{
Packit 577717
//  printf("_bgp_read:  this_state* = %p\n", this_state);
Packit 577717
//  printf("_bgp_read:  (long_long*)&this_state->counters[0] = %p\n", (long_long*)&this_state->counters[0]);
Packit 577717
//  printf("_bgp_read:  (long_long*)&this_state->counters[1] = %p\n", (long_long*)&this_state->counters[1]);
Packit 577717
Packit 577717
	
Packit 577717
	sigset_t mask_set;
Packit 577717
	sigset_t old_set;
Packit 577717
	sigemptyset( &mask_set );
Packit 577717
	sigaddset( &mask_set, SIGXCPU );
Packit 577717
	sigprocmask( SIG_BLOCK, &mask_set, &old_set );
Packit 577717
Packit 577717
	if ( BGP_UPC_Read_Counters
Packit 577717
		 ( ( long_long * ) & ctl->counters[0],
Packit 577717
		   BGP_UPC_MAXIMUM_LENGTH_READ_COUNTERS_ONLY,
Packit 577717
		   BGP_UPC_READ_EXCLUSIVE ) < 0 ) {
Packit 577717
		sigprocmask( SIG_UNBLOCK, &mask_set, NULL );
Packit 577717
		return PAPI_ECMP;
Packit 577717
	}
Packit 577717
	sigprocmask( SIG_UNBLOCK, &mask_set, NULL );
Packit 577717
        /* hack to emulate BGP_MISC_ELAPSED_TIME counter */
Packit 577717
        ctl->counters[255]=_bgp_GetTimeBase()-begin_cycles;
Packit 577717
	*dp = ( long_long * ) & ctl->counters[0];
Packit 577717
Packit 577717
//  printf("_bgp_read:  dp = %p\n", dp);
Packit 577717
//  printf("_bgp_read:  *dp = %p\n", *dp);
Packit 577717
//  printf("_bgp_read:  (*dp)[0]* = %p\n", &((*dp)[0]));
Packit 577717
//  printf("_bgp_read:  (*dp)[1]* = %p\n", &((*dp)[1]));
Packit 577717
//  printf("_bgp_read:  (*dp)[2]* = %p\n", &((*dp)[2]));
Packit 577717
//  int i;
Packit 577717
//  for (i=0; i<256; i++)
Packit 577717
//    if ((*dp)[i])
Packit 577717
//      printf("_bgp_read: i=%d, (*dp)[i]=%lld\n", i, (*dp)[i]);
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Reset
Packit 577717
 *
Packit 577717
 * Zero the counter values
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_reset( hwd_context_t * ctx, hwd_control_state_t * ctrlstate )
Packit 577717
{
Packit 577717
// NOTE:  PAPI can reset the counters with the UPC running.  One way it happens
Packit 577717
//        is with PAPI_accum.  In that case, stop and restart the UPC, resetting
Packit 577717
//        the counters.
Packit 577717
	sigset_t mask_set;
Packit 577717
	sigset_t old_set;
Packit 577717
	sigemptyset( &mask_set );
Packit 577717
	sigaddset( &mask_set, SIGXCPU );
Packit 577717
	sigprocmask( SIG_BLOCK, &mask_set, &old_set );
Packit 577717
	if ( BGP_UPC_Check_Active(  ) ) {
Packit 577717
		// printf("_bgp_reset:  BGP_UPC_Stop()\n");
Packit 577717
		BGP_UPC_Stop(  );
Packit 577717
		// printf("_bgp_reset:  BGP_UPC_Start(BGP_UPC_RESET_COUNTERS)\n");
Packit 577717
		BGP_UPC_Start( BGP_UPC_RESET_COUNTERS );
Packit 577717
	} else {
Packit 577717
		// printf("_bgp_reset:  BGP_UPC_Zero_Counter_Values()\n");
Packit 577717
		BGP_UPC_Zero_Counter_Values(  );
Packit 577717
	}
Packit 577717
	sigprocmask( SIG_UNBLOCK, &mask_set, NULL );
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Shutdown
Packit 577717
 *
Packit 577717
 * This routine is for shutting down threads,
Packit 577717
 * including the master thread.
Packit 577717
 * Effectively a no-op, same as BG/L...
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_shutdown( hwd_context_t * ctx )
Packit 577717
{
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Write
Packit 577717
 *
Packit 577717
 * Write counter values
Packit 577717
 * NOTE:  Could possible support, but signal error as BG/L does...
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_write( hwd_context_t * ctx, hwd_control_state_t * cntrl, long_long * from )
Packit 577717
{
Packit 577717
Packit 577717
	return PAPI_ECMP;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Dispatch Timer
Packit 577717
 *
Packit 577717
 * Same as BG/L - simple return
Packit 577717
 */
Packit 577717
void
Packit 577717
_bgp_dispatch_timer( int signal, hwd_siginfo_t * si, void *context )
Packit 577717
{
Packit 577717
Packit 577717
	return;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
Packit 577717
Packit 577717
void
Packit 577717
user_signal_handler( int signum, hwd_siginfo_t * siginfo, void *mycontext )
Packit 577717
{
Packit 577717
Packit 577717
	EventSetInfo_t *ESI;
Packit 577717
	ThreadInfo_t *thread = NULL;
Packit 577717
	int isHardware = 1;
Packit 577717
	caddr_t pc;
Packit 577717
	_papi_hwi_context_t ctx;
Packit 577717
	BGP_UPC_Event_Id_t xEventId = 0;
Packit 577717
//  int thresh;
Packit 577717
	int event_index, i;
Packit 577717
	long_long overflow_bit = 0;
Packit 577717
	int64_t threshold;
Packit 577717
Packit 577717
	ctx.si = siginfo;
Packit 577717
	ctx.ucontext = ( ucontext_t * ) mycontext;
Packit 577717
Packit 577717
	ucontext_t *context = ( ucontext_t * ) mycontext;
Packit 577717
	pc = ( caddr_t ) context->uc_mcontext.regs->nip;
Packit 577717
	thread = _papi_hwi_lookup_thread( 0 );
Packit 577717
	//int cidx = (int) &thread;
Packit 577717
	ESI = thread->running_eventset[0];
Packit 577717
	//ESI = (EventSetInfo_t *) thread->running_eventset;
Packit 577717
Packit 577717
	if ( ESI == NULL ) {
Packit 577717
		//printf("ESI is null\n");
Packit 577717
		return;
Packit 577717
	} else {
Packit 577717
		BGP_UPC_Stop(  );
Packit 577717
		//xEventId = get_bgp_native_event_id(ESI->NativeInfoArray[0].ni_event); //*ESI->overflow.EventIndex].ni_event);
Packit 577717
		event_index = *ESI->overflow.EventIndex;
Packit 577717
		//printf("event index %d\n", event_index);
Packit 577717
Packit 577717
		for ( i = 0; i <= event_index; i++ ) {
Packit 577717
			xEventId =
Packit 577717
				get_bgp_native_event_id( ESI->NativeInfoArray[i].ni_event );
Packit 577717
			if ( BGP_UPC_Read_Counter( xEventId, 1 ) >=
Packit 577717
				 BGP_UPC_Get_Counter_Threshold_Value( xEventId ) &&
Packit 577717
				 BGP_UPC_Get_Counter_Threshold_Value( xEventId ) != 0 ) {
Packit 577717
				break;
Packit 577717
			}
Packit 577717
		}
Packit 577717
		overflow_bit ^= 1 << xEventId;
Packit 577717
		//ESI->overflow.handler(ESI->EventSetIndex, pc, 0, (void *) &ctx;; 
Packit 577717
		_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, pc, &isHardware,
Packit 577717
											overflow_bit, 0, &thread, 0 );
Packit 577717
		//thresh = (int)(*ESI->overflow.threshold + BGP_UPC_Read_Counter_Value(xEventId, 1)); //(int)BGP_UPC_Get_Counter_Threshold_Value(xEventId));
Packit 577717
		//printf("thresh %llu val %llu\n", (int64_t)*ESI->overflow.threshold, BGP_UPC_Read_Counter_Value(xEventId, 1));
Packit 577717
		threshold =
Packit 577717
			( int64_t ) * ESI->overflow.threshold +
Packit 577717
			BGP_UPC_Read_Counter_Value( xEventId, 1 );
Packit 577717
		//printf("threshold %llu\n", threshold);
Packit 577717
		BGP_UPC_Set_Counter_Threshold_Value( xEventId, threshold );
Packit 577717
		BGP_UPC_Start( 0 );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Set Overflow
Packit 577717
 *
Packit 577717
 * This is commented out in BG/L - need to explore and complete...
Packit 577717
 * However, with true 64-bit counters in BG/P 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
 * Commented out code is carry-over from BG/L...
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit 577717
{
Packit 577717
	int rc = 0;
Packit 577717
	BGP_UPC_Event_Id_t xEventId;	   // = get_bgp_native_event_id(EventCode);
Packit 577717
	xEventId =
Packit 577717
		get_bgp_native_event_id( ESI->NativeInfoArray[EventIndex].ni_event );
Packit 577717
	//rc = BGP_UPC_Monitor_Event(xEventId, BGP_UPC_CFG_LEVEL_HIGH);
Packit 577717
	rc = BGP_UPC_Set_Counter_Threshold_Value( xEventId, threshold );
Packit 577717
Packit 577717
	//printf("setting up sigactioni %d\n", xEventId); //ESI->NativeInfoArray[EventIndex].ni_event);
Packit 577717
	/*struct sigaction act;
Packit 577717
	   act.sa_sigaction = user_signal_handler;
Packit 577717
	   memset(&act.sa_mask, 0x0, sizeof(act.sa_mask));
Packit 577717
	   act.sa_flags = SA_RESTART | SA_SIGINFO;
Packit 577717
	   if (sigaction(SIGXCPU, &act, NULL) == -1) {
Packit 577717
	   return (PAPI_ESYS);
Packit 577717
	   } */
Packit 577717
Packit 577717
	struct sigaction new_action;
Packit 577717
	sigemptyset( &new_action.sa_mask );
Packit 577717
	new_action.sa_sigaction = ( void * ) user_signal_handler;
Packit 577717
	new_action.sa_flags = SA_RESTART | SA_SIGINFO;
Packit 577717
	sigaction( SIGXCPU, &new_action, NULL );
Packit 577717
Packit 577717
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*
Packit 577717
 * Set Profile
Packit 577717
 *
Packit 577717
 * Same as for BG/L, routine not used and returns error
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold )
Packit 577717
{
Packit 577717
	/* This function is not used and shouldn't be called. */
Packit 577717
Packit 577717
	return PAPI_ECMP;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Stop Profiling
Packit 577717
 *
Packit 577717
 * Same as for BG/L...
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_stop_profiling( ThreadInfo_t * master, EventSetInfo_t * ESI )
Packit 577717
{
Packit 577717
	return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Control
Packit 577717
 *
Packit 577717
 * Same as for BG/L - initialize the domain
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
Packit 577717
{
Packit 577717
//  extern int _bgp_set_domain(hwd_control_state_t * cntrl, int domain);
Packit 577717
Packit 577717
	switch ( code ) {
Packit 577717
	case PAPI_DOMAIN:
Packit 577717
	case PAPI_DEFDOM:
Packit 577717
//    Simply return PAPI_OK, as no state is kept.
Packit 577717
		return PAPI_OK;
Packit 577717
	case PAPI_GRANUL:
Packit 577717
	case PAPI_DEFGRN:
Packit 577717
		return PAPI_ECMP;
Packit 577717
	default:
Packit 577717
		return PAPI_EINVAL;
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Get Real Micro-seconds
Packit 577717
 */
Packit 577717
long long
Packit 577717
_bgp_get_real_usec( void )
Packit 577717
{
Packit 577717
	/*
Packit 577717
	 * NOTE:  _papi_hwi_system_info.hw_info.mhz is really a representation of unit of time per cycle.
Packit 577717
	 *        On BG/P, it's value is 8.5e-4.  Therefore, to get cycles per sec, we have to multiply
Packit 577717
	 *        by 1.0e12.  To then convert to usec, we have to divide by 1.0e-3.
Packit 577717
	 */
Packit 577717
Packit 577717
//  SUBDBG("_bgp_get_real_usec:  _papi_hwi_system_info.hw_info.mhz=%e\n",(_papi_hwi_system_info.hw_info.mhz));
Packit 577717
//  float x = (float)get_cycles();
Packit 577717
//  float y = (_papi_hwi_system_info.hw_info.mhz)*(1.0e9);
Packit 577717
//  SUBDBG("_bgp_get_real_usec: _papi_hwi_system_info.hw_info.mhz=%e, x=%e, y=%e, x/y=%e, (long long)(x/y) = %lld\n",
Packit 577717
//         (_papi_hwi_system_info.hw_info.mhz), x, y, x/y, (long long)(x/y));
Packit 577717
//  return (long long)(x/y);
Packit 577717
Packit 577717
	return ( ( long long ) ( ( ( float ) get_cycles(  ) ) /
Packit 577717
	       ( ( _papi_hwi_system_info.hw_info.cpu_max_mhz ) ) ) );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Get Real Cycles
Packit 577717
 *
Packit 577717
 * Same for BG/L, using native function...
Packit 577717
 */
Packit 577717
long long
Packit 577717
_bgp_get_real_cycles( void )
Packit 577717
{
Packit 577717
Packit 577717
	return ( get_cycles(  ) );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Get Virtual Micro-seconds
Packit 577717
 *
Packit 577717
 * Same calc as for BG/L, returns real usec...
Packit 577717
 */
Packit 577717
long long
Packit 577717
_bgp_get_virt_usec( void )
Packit 577717
{
Packit 577717
Packit 577717
	return _bgp_get_real_usec(  );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Get Virtual Cycles
Packit 577717
 *
Packit 577717
 * Same calc as for BG/L, returns real cycles...
Packit 577717
 */
Packit 577717
long long
Packit 577717
_bgp_get_virt_cycles( void )
Packit 577717
{
Packit 577717
Packit 577717
	return _bgp_get_real_cycles(  );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Component setup and shutdown
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
_bgp_init_component( int cidx )
Packit 577717
{
Packit 577717
	int retval;
Packit 577717
Packit 577717
	_bgp_vectors.cmp_info.CmpIdx = cidx;
Packit 577717
	retval = _bgp_init_global(  );
Packit 577717
	
Packit 577717
	return ( retval );
Packit 577717
}
Packit 577717
Packit 577717
Packit 577717
/*************************************/
Packit 577717
/* CODE TO SUPPORT OPAQUE NATIVE MAP */
Packit 577717
/*************************************/
Packit 577717
/*
Packit 577717
 * Native Code to Event Name
Packit 577717
 *
Packit 577717
 * Given a native event code, returns the short text label
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_ntv_code_to_name( unsigned int EventCode, char *name, int len )
Packit 577717
{
Packit 577717
Packit 577717
	char xNativeEventName[BGP_UPC_MAXIMUM_LENGTH_EVENT_NAME];
Packit 577717
	BGP_UPC_Event_Id_t xEventId = get_bgp_native_event_id( EventCode );
Packit 577717
	/*
Packit 577717
	 * NOTE:  We do not return the event name for a user mode 2 or 3 event...
Packit 577717
	 */
Packit 577717
	if ( ( int ) xEventId < 0 || ( int ) xEventId > 511 )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
	if ( BGP_UPC_Get_Event_Name
Packit 577717
		 ( xEventId, BGP_UPC_MAXIMUM_LENGTH_EVENT_NAME,
Packit 577717
		   xNativeEventName ) != BGP_UPC_SUCCESS )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
	SUBDBG( "_bgp_ntv_code_to_name:  EventCode = %d\n, xEventName = %s\n",
Packit 577717
			EventCode, xEventName );
Packit 577717
	strncpy( name, "PNE_", len );
Packit 577717
	strncat( name, xNativeEventName, len - strlen( name ) );
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Native Code to Event Description
Packit 577717
 *
Packit 577717
 * Given a native event code, returns the longer native event description
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
Packit 577717
{
Packit 577717
Packit 577717
	char xNativeEventDesc[BGP_UPC_MAXIMUM_LENGTH_EVENT_DESCRIPTION];
Packit 577717
Packit 577717
	BGP_UPC_Event_Id_t xEventId = get_bgp_native_event_id( EventCode );
Packit 577717
	/*
Packit 577717
	 * NOTE:  We do not return the event name for a user mode 2 or 3 event...
Packit 577717
	 */
Packit 577717
	if ( ( int ) xEventId < 0 || ( int ) xEventId > 511 )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	else if ( BGP_UPC_Get_Event_Description
Packit 577717
			  ( xEventId, BGP_UPC_MAXIMUM_LENGTH_EVENT_DESCRIPTION,
Packit 577717
				xNativeEventDesc ) != BGP_UPC_SUCCESS )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
Packit 577717
	strncpy( name, xNativeEventDesc, len );
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Native Code to Bit Configuration
Packit 577717
 *
Packit 577717
 * Given a native event code, assigns the native event's
Packit 577717
 * information to a given pointer.
Packit 577717
 * NOTE: The info must be COPIED to location addressed by
Packit 577717
 *       the provided pointer, not just referenced!
Packit 577717
 * NOTE: For BG/P, the bit configuration is not needed,
Packit 577717
 *       as the native SPI is used to configure events.
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
Packit 577717
{
Packit 577717
Packit 577717
	return ( PAPI_OK );
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * Native ENUM Events
Packit 577717
 *
Packit 577717
 * Given a native event code, looks for next MOESI bit if applicable.
Packit 577717
 * If not, looks for the next event in the table if the next one exists.
Packit 577717
 * If not, returns the proper error code.
Packit 577717
 *
Packit 577717
 * For BG/P, we simply we simply return the native event id to the
Packit 577717
 * to the next logical non-reserved event id.
Packit 577717
 *
Packit 577717
 * We only support enumerating all or available events.
Packit 577717
 */
Packit 577717
int
Packit 577717
_bgp_ntv_enum_events( unsigned int *EventCode, int modifier )
Packit 577717
{
Packit 577717
	/*
Packit 577717
	 * Check for a valid EventCode and we only process a modifier of 'all events'...
Packit 577717
	 */
Packit 577717
//  printf("_bgp_ntv_enum_events:  EventCode=%8.8x\n", *EventCode);
Packit 577717
	if ( *EventCode < 0x40000000 || *EventCode > 0x400001FF ||
Packit 577717
		 ( modifier != PAPI_ENUM_ALL && modifier != PAPI_PRESET_ENUM_AVAIL ) )
Packit 577717
		return PAPI_ECMP;
Packit 577717
Packit 577717
	char xNativeEventName[BGP_UPC_MAXIMUM_LENGTH_EVENT_NAME];
Packit 577717
	BGP_UPC_RC_t xRC;
Packit 577717
Packit 577717
	// NOTE:  We turn off the PAPI_NATIVE bit here...
Packit 577717
	int32_t xNativeEventId =
Packit 577717
		( ( *EventCode ) & PAPI_NATIVE_AND_MASK ) + 0x00000001;
Packit 577717
	while ( xNativeEventId <= 0x000001FF ) {
Packit 577717
		xRC =
Packit 577717
			BGP_UPC_Get_Event_Name( xNativeEventId,
Packit 577717
									BGP_UPC_MAXIMUM_LENGTH_EVENT_NAME,
Packit 577717
									xNativeEventName );
Packit 577717
//    printf("_bgp_ntv_enum_events:  xNativeEventId = %8.8x, xRC=%d\n", xNativeEventId, xRC);
Packit 577717
		if ( ( xRC == BGP_UPC_SUCCESS ) && ( strlen( xNativeEventName ) > 0 ) ) {
Packit 577717
//      printf("_bgp_ntv_enum_events:  len(xNativeEventName)=%d, xNativeEventName=%s\n", strlen(xNativeEventName), xNativeEventName);
Packit 577717
			break;
Packit 577717
		}
Packit 577717
		xNativeEventId++;
Packit 577717
	}
Packit 577717
Packit 577717
	if ( xNativeEventId > 0x000001FF )
Packit 577717
		return ( PAPI_ENOEVNT );
Packit 577717
	else {
Packit 577717
		// NOTE:  We turn the PAPI_NATIVE bit back on here...
Packit 577717
		*EventCode = xNativeEventId | PAPI_NATIVE_MASK;
Packit 577717
		return ( PAPI_OK );
Packit 577717
	}
Packit 577717
}
Packit 577717
Packit 577717
int 
Packit 577717
_papi_hwi_init_os(void) {
Packit 577717
Packit 577717
    struct utsname uname_buffer;
Packit 577717
Packit 577717
    uname(&uname_buffer);
Packit 577717
Packit 577717
    strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN);
Packit 577717
Packit 577717
    strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN);
Packit 577717
Packit 577717
    _papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL;
Packit 577717
    _papi_os_info.itimer_num = PAPI_INT_ITIMER;
Packit 577717
    _papi_os_info.itimer_res_ns = 1;
Packit 577717
Packit 577717
    return PAPI_OK;
Packit 577717
}
Packit 577717
Packit 577717
/*
Packit 577717
 * PAPI Vector Table for BG/P
Packit 577717
 */
Packit 577717
papi_vector_t _bgp_vectors = {
Packit 577717
	.cmp_info = {
Packit 577717
             .name = "linux-bgp",
Packit 577717
	     .short_name = "bgp",
Packit 577717
	     .description = "BlueGene/P component",
Packit 577717
	     .num_cntrs = BGP_UPC_MAX_MONITORED_EVENTS,
Packit 577717
	     .num_mpx_cntrs = BGP_UPC_MAX_MONITORED_EVENTS,
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
	     .hardware_intr_sig = PAPI_INT_SIGNAL,
Packit 577717
	     .hardware_intr = 1,
Packit 577717
	     .fast_real_timer = 1,
Packit 577717
	     .fast_virtual_timer = 0,
Packit 577717
  },
Packit 577717
Packit 577717
  /* Sizes of framework-opaque component-private structures */
Packit 577717
  .size = {
Packit 577717
	     .context = sizeof ( hwd_context_t ),
Packit 577717
	     .control_state = sizeof ( hwd_control_state_t ),
Packit 577717
	     .reg_value = sizeof ( hwd_register_t ),
Packit 577717
	     .reg_alloc = sizeof ( hwd_reg_alloc_t ),
Packit 577717
  },
Packit 577717
  /* Function pointers in this component */
Packit 577717
  .dispatch_timer = _bgp_dispatch_timer,
Packit 577717
  .start = _bgp_start,
Packit 577717
  .stop = _bgp_stop,
Packit 577717
  .read = _bgp_read,
Packit 577717
  .reset = _bgp_reset,
Packit 577717
  .write = _bgp_write,
Packit 577717
  .stop_profiling = _bgp_stop_profiling,
Packit 577717
  .init_component = _bgp_init_component,
Packit 577717
  .init_thread = _bgp_init_thread,
Packit 577717
  .init_control_state = _bgp_init_control_state,
Packit 577717
  .update_control_state = _bgp_update_control_state,
Packit 577717
  .ctl = _bgp_ctl,
Packit 577717
  .set_overflow = _bgp_set_overflow,
Packit 577717
  .set_profile = _bgp_set_profile,
Packit 577717
  .set_domain = _bgp_set_domain,
Packit 577717
  .ntv_enum_events = _bgp_ntv_enum_events,
Packit 577717
  .ntv_code_to_name = _bgp_ntv_code_to_name,
Packit 577717
  .ntv_code_to_descr = _bgp_ntv_code_to_descr,
Packit 577717
  .ntv_code_to_bits = _bgp_ntv_code_to_bits,
Packit 577717
  .allocate_registers = _bgp_allocate_registers,
Packit 577717
  .shutdown_thread = _bgp_shutdown
Packit 577717
};
Packit 577717
Packit 577717
papi_os_vector_t _papi_os_vector = {
Packit 577717
	.get_memory_info = _bgp_get_memory_info,
Packit 577717
	.get_dmem_info = _bgp_get_dmem_info,
Packit 577717
	.get_real_cycles = _bgp_get_real_cycles,
Packit 577717
	.get_real_usec = _bgp_get_real_usec,
Packit 577717
	.get_virt_cycles = _bgp_get_virt_cycles,
Packit 577717
	.get_virt_usec = _bgp_get_virt_usec,
Packit 577717
	.get_system_info = _bgp_get_system_info,
Packit 577717
};