PAPI  5.1.0.2
linux-bgq.c
Go to the documentation of this file.
00001 /****************************/
00002 /* THIS IS OPEN SOURCE CODE */
00003 /****************************/
00004 
00020 #include "papi.h"
00021 #include "papi_internal.h"
00022 #include "papi_lock.h"
00023 #include "papi_memory.h"
00024 #include "extras.h"
00025 
00026 #include "linux-bgq.h"
00027 
00028 #include "papi_vector.h"
00029 #include "error.h"
00030 
00031 /*
00032  * BG/Q specific 'stuff'
00033  */
00034 #include <ucontext.h>
00035 #include <stdlib.h>
00036 #include <signal.h>
00037 #include <sys/time.h>
00038 #include <errno.h>
00039 #include <stdio.h>
00040 #include <string.h>
00041 #include <sys/utsname.h>
00042 #include "spi/include/upci/upci.h"
00043 #ifdef DEBUG_BGQ
00044 #include <inttypes.h>
00045 #endif
00046 
00047 // BG/Q macros
00048 #define get_cycles GetTimeBase
00049 
00050 // BG/Q external structures/functions/stuff
00051 #if 1
00052 UPC_Lock_t thdLocks[PAPI_MAX_LOCK];
00053 #else
00054 pthread_mutex_t thdLocks[PAPI_MAX_LOCK];
00055 #endif
00056 
00057 /* Defined in papi_data.c */
00058 //extern papi_mdi_t _papi_hwi_system_info;
00059 
00060 papi_vector_t _bgq_vectors;
00061 PAPI_os_info_t _papi_os_info;
00062 
00063 #define OPCODE_EVENT_CHUNK 8
00064 static int allocated_opcode_events = 0;
00065 static int num_opcode_events = 0;
00066 
00067 struct bgq_generic_events_t {
00068     int idx;
00069     int eventId;
00070     char mask[PAPI_MIN_STR_LEN];
00071     char opcode[PAPI_MIN_STR_LEN];
00072     uint64_t opcode_mask;
00073 };
00074 
00075 static struct bgq_generic_events_t *GenericEvent;
00076 
00077 /* Defined in linux-bgq-memory.c */
00078 extern int _bgq_get_memory_info( PAPI_hw_info_t * pHwInfo, int pCPU_Type );
00079 extern int _bgq_get_dmem_info( PAPI_dmem_info_t * pDmemInfo );
00080 
00081 /* prototypes */
00082 void user_signal_handler( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext );
00083 
00084 /*******************************************************************************
00085  ********  BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT **********
00086  ******************************************************************************/
00087 
00088 
00089 /*
00090  * Lock
00091  */
00092 void
00093 _papi_hwd_lock( int lock ) 
00094 {
00095 #ifdef DEBUG_BGQ
00096     printf( _AT_ " _papi_hwd_lock %d\n", lock);
00097 #endif
00098     assert( lock < PAPI_MAX_LOCK );
00099 #if 1
00100     UPC_Lock( &thdLocks[lock] );
00101 #else
00102     pthread_mutex_lock( &thdLocks[lock] );
00103 #endif
00104     
00105 #ifdef DEBUG_BGQ
00106     printf( _AT_ " _papi_hwd_lock got lock %d\n", lock );
00107 #endif
00108     
00109     return;
00110 }
00111 
00112 /*
00113  * Unlock
00114  */
00115 void
00116 _papi_hwd_unlock( int lock )
00117 {
00118 #ifdef DEBUG_BGQ
00119     printf( _AT_ " _papi_hwd_unlock %d\n", lock );
00120 #endif
00121     assert( lock < PAPI_MAX_LOCK );
00122 #if 1
00123     UPC_Unlock( &thdLocks[lock] );
00124 #else
00125     pthread_mutex_unlock( &thdLocks[lock] );
00126 #endif
00127     
00128     return;
00129 }
00130 
00131 
00132 /*
00133  * Get System Information
00134  *
00135  * Initialize system information structure
00136  */
00137 int
00138 _bgq_get_system_info( papi_mdi_t *mdi )
00139 {
00140 #ifdef DEBUG_BGQ
00141     printf( "_bgq_get_system_info\n" );
00142 #endif
00143     
00144     ( void ) mdi;
00145     Personality_t personality;
00146     int retval;
00147     
00148     /* Hardware info */
00149     retval = Kernel_GetPersonality( &personality, sizeof( Personality_t ) );
00150     if ( retval ) {
00151         fprintf( stdout, "Kernel_GetPersonality returned %d (sys error=%d).\n"
00152                 "\t%s\n", retval, errno, strerror( errno ) );
00153         return PAPI_ESYS;
00154     }
00155 
00156     /* Returns the number of processors that are associated with the currently
00157      * running process */
00158     _papi_hwi_system_info.hw_info.ncpu = Kernel_ProcessorCount( );
00159     // TODO: HJ Those values need to be fixed
00160     _papi_hwi_system_info.hw_info.nnodes = Kernel_ProcessCount( );
00161     _papi_hwi_system_info.hw_info.totalcpus = _papi_hwi_system_info.hw_info.ncpu;
00162     
00163     _papi_hwi_system_info.hw_info.cpu_max_mhz = personality.Kernel_Config.FreqMHz;
00164     _papi_hwi_system_info.hw_info.cpu_min_mhz = personality.Kernel_Config.FreqMHz;
00165 
00166     _papi_hwi_system_info.hw_info.mhz = ( float ) personality.Kernel_Config.FreqMHz;
00167     SUBDBG( "_bgq_get_system_info:  Detected MHZ is %f\n",
00168            _papi_hwi_system_info.hw_info.mhz );
00169 
00170     return ( PAPI_OK );
00171 }
00172 
00173 
00174 /*
00175  * Initialize Control State
00176  *
00177  */
00178 int
00179 _bgq_init_control_state( hwd_control_state_t * ptr )
00180 {
00181 #ifdef DEBUG_BGQ
00182     printf( "_bgq_init_control_state\n" );
00183 #endif
00184     
00185     ptr->EventGroup = Bgpm_CreateEventSet();
00186     CHECK_BGPM_ERROR( ptr->EventGroup, "Bgpm_CreateEventSet" );
00187     
00188     // initialize multiplexing flag to OFF (0)
00189     ptr->muxOn = 0;
00190     // initialize overflow flag to OFF (0)
00191     ptr->overflow = 0;
00192     ptr->overflow_threshold = 0;
00193     ptr->overflow_EventIndex = 0;
00194     // initialized BGPM eventGroup flag to NOT applied yet (0)
00195     ptr->bgpm_eventset_applied = 0;
00196     
00197     return PAPI_OK;
00198 }
00199 
00200 
00201 /*
00202  * Set Domain
00203  */
00204 int
00205 _bgq_set_domain( hwd_control_state_t * cntrl, int domain )
00206 {
00207 #ifdef DEBUG_BGQ
00208     printf( "_bgq_set_domain\n" );
00209 #endif
00210     int found = 0;
00211     ( void ) cntrl;
00212     
00213     if ( PAPI_DOM_USER & domain )
00214         found = 1;
00215     
00216     if ( PAPI_DOM_KERNEL & domain )
00217         found = 1;
00218     
00219     if ( PAPI_DOM_OTHER & domain )
00220         found = 1;
00221     
00222     if ( !found )
00223         return ( PAPI_EINVAL );
00224     
00225     return ( PAPI_OK );
00226 }
00227 
00228 /*
00229  * PAPI Initialization
00230  * This is called whenever a thread is initialized
00231  */
00232 int
00233 _bgq_init( hwd_context_t * ctx )
00234 {
00235 #ifdef DEBUG_BGQ
00236     printf( "_bgq_init\n" );
00237 #endif
00238     ( void ) ctx;
00239     int retval;
00240 
00241 #ifdef DEBUG_BGPM
00242     Bgpm_PrintOnError(1);
00243     Bgpm_ExitOnError(0);
00244 #else
00245     Bgpm_PrintOnError(0);
00246     // avoid bgpm default of exiting when error occurs - caller will check return code instead.
00247     Bgpm_ExitOnError(0);    
00248 #endif
00249     
00250     retval = Bgpm_Init( BGPM_MODE_SWDISTRIB );
00251     CHECK_BGPM_ERROR( retval, "Bgpm_Init" );
00252 
00253     //_common_initBgpm();
00254     
00255     return PAPI_OK; 
00256 }
00257 
00258 
00259 int
00260 _bgq_multiplex( hwd_control_state_t * bgq_state )
00261 {
00262     int retval;
00263     uint64_t bgpm_period;
00264     double Sec, Hz; 
00265 
00266 #ifdef DEBUG_BGQ
00267     printf("_bgq_multiplex BEGIN: Num of Events = %d (vs %d)\n", Bgpm_NumEvents( bgq_state->EventGroup ), bgq_state->count );
00268 #endif
00269     
00270     // convert Mhz to Hz ( = cycles / sec )
00271     Hz = (double) _papi_hwi_system_info.hw_info.cpu_max_mhz * 1000 * 1000;
00272     // convert PAPI multiplex period (in ns) to BGPM period (in cycles)
00273     Sec = (double) _papi_os_info.itimer_ns / ( 1000 * 1000 * 1000 );
00274     bgpm_period = Hz * Sec;
00275 
00276     // if EventGroup is not empty -- which is required by BGPM before 
00277     // we can call SetMultiplex() -- then drain the events from the 
00278     // BGPM EventGroup, turn on multiplex flag, and rebuild BGPM EventGroup.
00279     if ( 0 < bgq_state->count ) {
00280         // Delete and re-create BGPM eventset
00281         _common_deleteRecreate( &bgq_state->EventGroup );
00282         
00283         // turn on multiplex for BGPM
00284         retval = Bgpm_SetMultiplex( bgq_state->EventGroup, bgpm_period, BGPM_NORMAL );      
00285         CHECK_BGPM_ERROR( retval, "Bgpm_SetMultiplex" );
00286         
00287         // rebuild BGPM EventGroup
00288         _common_rebuildEventgroup( bgq_state->count, 
00289                                    bgq_state->EventGroup_local, 
00290                                    &bgq_state->EventGroup );        
00291     }
00292     else {
00293         // need to pass either BGPM_NORMAL or BGPM_NOTNORMAL 
00294         // BGPM_NORMAL: numbers reported by Bgpm_ReadEvent() are normalized 
00295         // to the maximum time spent in a multiplexed group
00296         retval = Bgpm_SetMultiplex( bgq_state->EventGroup, bgpm_period, BGPM_NORMAL );      
00297         CHECK_BGPM_ERROR( retval, "Bgpm_SetMultiplex" );                
00298     }
00299 
00300 #ifdef DEBUG_BGQ
00301     printf("_bgq_multiplex END: Num of Events = %d (vs %d) --- retval = %d\n", 
00302            Bgpm_NumEvents( bgq_state->EventGroup ), bgq_state->count, retval );
00303 #endif
00304     
00305     return ( retval );
00306 }
00307 
00308 
00309 
00310 
00311 
00312 /*
00313  * Register Allocation
00314  *
00315  */
00316 int
00317 _bgq_allocate_registers( EventSetInfo_t * ESI )
00318 {
00319 #ifdef DEBUG_BGQ
00320     printf("_bgq_allocate_registers\n");
00321 #endif
00322     int i, natNum;
00323     int xEventId;
00324 
00325     /*
00326      * Start monitoring the events...
00327      */
00328     natNum = ESI->NativeCount;
00329 
00330     for ( i = 0; i < natNum; i++ ) {
00331         xEventId = ( ESI->NativeInfoArray[i].ni_event & PAPI_NATIVE_AND_MASK ) + 1;
00332         ESI->NativeInfoArray[i].ni_position = i;        
00333     }
00334 
00335     return PAPI_OK;
00336 }
00337 
00338 
00339 /*
00340  * PAPI Cleanup Eventset
00341  *
00342  * Destroy and re-create the BGPM / Punit EventSet
00343  */
00344 int
00345 _bgq_cleanup_eventset( hwd_control_state_t * ctrl )
00346 {
00347 #ifdef DEBUG_BGQ
00348     printf( "_bgq_cleanup_eventset\n" );
00349 #endif
00350     
00351     // set multiplexing flag to OFF (0)
00352     ctrl->muxOn = 0;
00353     // set overflow flag to OFF (0)
00354     ctrl->overflow = 0;
00355     ctrl->overflow_threshold = 0;
00356     ctrl->overflow_EventIndex = 0;
00357     // set BGPM eventGroup flag back to NOT applied yet (0)
00358     ctrl->bgpm_eventset_applied = 0;
00359 
00360     return ( PAPI_OK );
00361 }
00362 
00363 
00364 /*
00365  * Update Control State
00366  *
00367  * This function clears the current contents of the control
00368  * structure and updates it with whatever resources are allocated
00369  * for all the native events in the native info structure array.
00370  */
00371 int
00372 _bgq_update_control_state( hwd_control_state_t * ptr,
00373                            NativeInfo_t * native, int count,
00374                            hwd_context_t * ctx )
00375 {
00376 #ifdef DEBUG_BGQ
00377     printf( _AT_ " _bgq_update_control_state: count = %d, EventGroup=%d\n", count, ptr->EventGroup );
00378 #endif
00379     ( void ) ctx;
00380     int i, j, index, retval;
00381     unsigned evtIdx;
00382     
00383     // Delete and re-create BGPM eventset
00384     _common_deleteRecreate( &ptr->EventGroup );
00385     
00386 #ifdef DEBUG_BGQ
00387     printf( _AT_ " _bgq_update_control_state: EventGroup=%d, muxOn = %d, overflow = %d\n",
00388            ptr->EventGroup, ptr->muxOn, ptr->overflow );
00389 #endif
00390     
00391     // add the events to the eventset
00392     for ( i = 0; i < count; i++ ) {
00393         index = ( native[i].ni_event & PAPI_NATIVE_AND_MASK ) + 1;
00394         
00395         ptr->EventGroup_local[i] = index;
00396 
00397         // we found an opcode event
00398         if ( index > BGQ_PUNIT_MAX_COUNTERS ) {
00399             for( j = 0; j < num_opcode_events; j++ ) {
00400 #ifdef DEBUG_BGQ
00401                 printf(_AT_ " _bgq_update_control_state: %d out of %d OPCODES\n",
00402                        j, num_opcode_events );
00403 #endif
00404 #ifdef DEBUG_BGQ
00405                 printf(_AT_ " _bgq_update_control_state: j's idx = %d, index = %d\n",
00406                        GenericEvent[j].idx, index );
00407 #endif
00408                 if ( GenericEvent[j].idx == ( index - 1) ) {
00409                     /* Add events to the BGPM eventGroup */
00410                     retval = Bgpm_AddEvent( ptr->EventGroup, GenericEvent[j].eventId );
00411                     CHECK_BGPM_ERROR( retval, "Bgpm_AddEvent" );
00412 #ifdef DEBUG_BGQ
00413                     printf(_AT_ " _bgq_update_control_state: ADD event: i = %d, eventId = %d\n", i, GenericEvent[j].eventId );
00414 #endif
00415                     
00416                     evtIdx = Bgpm_GetEventIndex( ptr->EventGroup,
00417                                                  GenericEvent[j].eventId,
00418                                                  i );
00419 #ifdef DEBUG_BGQ
00420                     printf(_AT_ " _bgq_update_control_state: evtIdx in EventGroup = %d\n",
00421                            evtIdx );
00422 #endif
00423                     if ( 0 == strcmp( GenericEvent[j].mask, "PEVT_INST_XU_GRP_MASK" ) ) {
00424                         retval = Bgpm_SetXuGrpMask( ptr->EventGroup,
00425                                                     evtIdx,
00426                                                     GenericEvent[j].opcode_mask );
00427                         CHECK_BGPM_ERROR( retval, "Bgpm_SetXuGrpMask" );
00428 #ifdef DEBUG_BGQ
00429                         printf(_AT_ " _bgq_update_control_state: it's PEVT_INST_XU_GRP_MASK\n" );
00430 #endif
00431                     } else if ( 0 == strcmp( GenericEvent[j].mask, "PEVT_INST_QFPU_GRP_MASK" ) ) {
00432                         retval = Bgpm_SetQfpuGrpMask( ptr->EventGroup,
00433                                                       evtIdx,
00434                                                       GenericEvent[j].opcode_mask );
00435                         CHECK_BGPM_ERROR( retval, "Bgpm_SetQfpuGrpMask" );
00436 #ifdef DEBUG_BGQ
00437                         printf(_AT_ " _bgq_update_control_state: it's PEVT_INST_QFPU_GRP_MASK\n" );
00438 #endif
00439                     }
00440                 }   
00441             }
00442         }
00443         else {
00444 #ifdef DEBUG_BGQ
00445             printf(_AT_ " _bgq_update_control_state: no OPCODE\n" );
00446 #endif
00447             
00448             /* Add events to the BGPM eventGroup */
00449             retval = Bgpm_AddEvent( ptr->EventGroup, index );
00450             CHECK_BGPM_ERROR( retval, "Bgpm_AddEvent" );
00451 #ifdef DEBUG_BGQ
00452             printf(_AT_ " _bgq_update_control_state: ADD event: i = %d, index = %d\n", i, index );
00453 #endif
00454             
00455         }
00456     }
00457     
00458     // store how many events we added to an EventSet
00459     ptr->count = count;
00460 
00461     // if muxOn and EventGroup is not empty -- which is required by BGPM before 
00462     // we can call SetMultiplex() -- then drain the events from the 
00463     // BGPM EventGroup, turn on multiplex flag, and rebuild BGPM EventGroup.
00464     if ( 1 == ptr->muxOn ) {
00465         retval = _bgq_multiplex( ptr );
00466     }
00467         
00468     // since update_control_state trashes overflow settings, this puts things
00469     // back into balance for BGPM 
00470     if ( 1 == ptr->overflow ) {
00471         _common_set_overflow_BGPM( ptr->EventGroup, 
00472                                    ptr->overflow_EventIndex, 
00473                                    ptr->overflow_threshold,
00474                                    user_signal_handler );
00475     }
00476         
00477     return ( PAPI_OK );
00478 }
00479 
00480 
00481 
00482 /*
00483  * PAPI Start
00484  */
00485 int
00486 _bgq_start( hwd_context_t * ctx, hwd_control_state_t * ptr )
00487 {
00488 #ifdef DEBUG_BGQ
00489     printf( "BEGIN _bgq_start\n" );
00490 #endif
00491     ( void ) ctx;
00492     int retval;
00493         
00494     retval = Bgpm_Apply( ptr->EventGroup ); 
00495     CHECK_BGPM_ERROR( retval, "Bgpm_Apply" );
00496     
00497     // set flag to 1: BGPM eventGroup HAS BEEN applied
00498     ptr->bgpm_eventset_applied = 1;
00499 
00500 #ifdef DEBUG_BGQ
00501     int i;
00502     int numEvts = Bgpm_NumEvents( ptr->EventGroup );
00503     for ( i = 0; i < numEvts; i++ ) {
00504         printf("%d = %s\n", i, Bgpm_GetEventLabel( ptr->EventGroup, i) );
00505     }
00506 #endif  
00507     
00508     /* Bgpm_Apply() does an implicit reset; 
00509      hence no need to use Bgpm_ResetStart */
00510     retval = Bgpm_Start( ptr->EventGroup );
00511     CHECK_BGPM_ERROR( retval, "Bgpm_Start" );
00512     
00513     return ( PAPI_OK );
00514 }
00515 
00516 /*
00517  * PAPI Stop
00518  */
00519 int
00520 _bgq_stop( hwd_context_t * ctx, hwd_control_state_t * ptr )
00521 {
00522 #ifdef DEBUG_BGQ
00523     printf( "BEGIN _bgq_stop\n" );
00524 #endif
00525     ( void ) ctx;
00526     int retval;
00527     
00528     retval = Bgpm_Stop( ptr->EventGroup );
00529     CHECK_BGPM_ERROR( retval, "Bgpm_Stop" );
00530     
00531     return ( PAPI_OK );
00532 }
00533 
00534 /*
00535  * PAPI Read Counters
00536  *
00537  * Read the counters into local storage
00538  */
00539 int
00540 _bgq_read( hwd_context_t * ctx, hwd_control_state_t * ptr,
00541            long_long ** dp, int flags )
00542 {
00543 #ifdef DEBUG_BGQ
00544     printf( "_bgq_read\n" );
00545 #endif
00546     ( void ) ctx;
00547     ( void ) flags;
00548     int i, numEvts;
00549     
00550     numEvts = Bgpm_NumEvents( ptr->EventGroup );
00551     if ( numEvts == 0 ) {
00552 #ifdef DEBUG_BGPM
00553         printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts );
00554         //return ( EXIT_FAILURE );
00555 #endif
00556     }
00557     
00558     for ( i = 0; i < numEvts; i++ ) 
00559         ptr->counters[i] = _common_getEventValue( i, ptr->EventGroup );
00560 
00561     *dp = ptr->counters;
00562         
00563     return ( PAPI_OK );
00564 }
00565 
00566 /*
00567  * PAPI Reset
00568  *
00569  * Zero the counter values
00570  */
00571 int
00572 _bgq_reset( hwd_context_t * ctx, hwd_control_state_t * ptr )
00573 {
00574 #ifdef DEBUG_BGQ
00575     printf( "_bgq_reset\n" );
00576 #endif
00577     ( void ) ctx;
00578     int retval;
00579     
00580     /* we can't simply call Bgpm_Reset() since PAPI doesn't have the 
00581        restriction that an EventSet has to be stopped before resetting is
00582        possible. However, BGPM does have this restriction. 
00583        Hence we need to stop, reset and start */
00584     retval = Bgpm_Stop( ptr->EventGroup );
00585     CHECK_BGPM_ERROR( retval, "Bgpm_Stop" );
00586     
00587     retval = Bgpm_ResetStart( ptr->EventGroup );
00588     CHECK_BGPM_ERROR( retval, "Bgpm_ResetStart" );
00589 
00590     return ( PAPI_OK );
00591 }
00592 
00593 
00594 /*
00595  * PAPI Shutdown
00596  *
00597  * This routine is for shutting down threads,
00598  * including the master thread.
00599  * Effectively a no-op, same as BG/L/P...
00600  */
00601 int
00602 _bgq_shutdown( hwd_context_t * ctx )
00603 {
00604 #ifdef DEBUG_BGQ
00605     printf( "_bgq_shutdown\n" );
00606 #endif
00607     ( void ) ctx;
00608     int retval;
00609     
00610     /* Disable BGPM library */  
00611     retval = Bgpm_Disable();
00612     CHECK_BGPM_ERROR( retval, "Bgpm_Disable" );
00613 
00614     return ( PAPI_OK );
00615     
00616 }
00617 
00618 /*
00619  * PAPI Write
00620  *
00621  * Write counter values
00622  * NOTE:  Could possible support, but signal error as BG/L/P does...
00623  */
00624 int
00625 _bgq_write( hwd_context_t * ctx, hwd_control_state_t * cntrl, long_long * from )
00626 {
00627 #ifdef DEBUG_BGQ
00628     printf( "_bgq_write\n" );
00629 #endif
00630     ( void ) ctx;
00631     ( void ) cntrl;
00632     ( void ) from;
00633     
00634     return PAPI_ECMP;
00635 }
00636 
00637 /*
00638  * Dispatch Timer
00639  *
00640  * NOT the same as BG/L/P where we simply return
00641  * This function is used when hardware overflows are working or when
00642  * software overflows are forced
00643  */
00644 void
00645 _bgq_dispatch_timer( int signal, hwd_siginfo_t * info, void *uc )
00646 {
00647     ( void ) signal;
00648     ( void ) info;
00649     ( void ) uc;
00650 #ifdef DEBUG_BGQ
00651     printf("BEGIN _bgq_dispatch_timer\n");
00652 #endif
00653     
00654     return;
00655 }
00656 
00657 
00658 
00659 /*
00660  * user_signal_handler
00661  *
00662  * This function is used when hardware overflows are working or when
00663  * software overflows are forced
00664  */
00665 void
00666 user_signal_handler( int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext )
00667 {
00668 #ifdef DEBUG_BGQ
00669     printf( "user_signal_handler start\n" );
00670 #endif
00671     ( void ) address;
00672     int retval; 
00673     unsigned i;
00674     int isHardware = 1;
00675     int cidx = _bgq_vectors.cmp_info.CmpIdx;
00676     long_long overflow_bit = 0;
00677     caddr_t address1;
00678     _papi_hwi_context_t ctx;
00679     ctx.ucontext = ( hwd_ucontext_t * ) pContext;
00680     ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
00681     
00682     //printf(_AT_ " thread = %p\n", thread);    // <<<<<<<<<<<<<<<<<<
00683     
00684     EventSetInfo_t *ESI;
00685     ESI = thread->running_eventset[cidx];
00686     // Get the indices of all events which have overflowed.
00687     unsigned ovfIdxs[BGPM_MAX_OVERFLOW_EVENTS];
00688     unsigned len = BGPM_MAX_OVERFLOW_EVENTS;
00689     
00690     retval = Bgpm_GetOverflowEventIndices( hEvtSet, ovfVector, ovfIdxs, &len );
00691 
00692     if ( retval < 0 ) {
00693 #ifdef DEBUG_BGPM
00694         printf ( "Error: ret value is %d for BGPM API function Bgpm_GetOverflowEventIndices.\n", 
00695                  retval ); 
00696 #endif
00697         return;
00698     }
00699         
00700     if ( thread == NULL ) {
00701         PAPIERROR( "thread == NULL in user_signal_handler!" );
00702         return;
00703     }
00704         
00705     if ( ESI == NULL ) {
00706         PAPIERROR( "ESI == NULL in user_signal_handler!");
00707         return;
00708     }
00709         
00710     if ( ESI->overflow.flags == 0 ) {
00711         PAPIERROR( "ESI->overflow.flags == 0 in user_signal_handler!");
00712         return;
00713     }
00714 
00715     for ( i = 0; i < len; i++ ) {
00716         uint64_t hProf;
00717         Bgpm_GetEventUser1( hEvtSet, ovfIdxs[i], &hProf );
00718         if ( hProf ) {
00719             overflow_bit ^= 1 << ovfIdxs[i];
00720             break;
00721         }
00722         
00723     }
00724     
00725     if ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) {
00726 #ifdef DEBUG_BGQ
00727         printf("OVERFLOW_SOFTWARE\n");
00728 #endif
00729         address1 = GET_OVERFLOW_ADDRESS( ctx );
00730         _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, NULL, 0, 0, &thread, cidx );
00731         return;
00732     }
00733     else if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
00734 #ifdef DEBUG_BGQ
00735         printf("OVERFLOW_HARDWARE\n");
00736 #endif
00737         address1 = GET_OVERFLOW_ADDRESS( ctx );
00738         _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, &isHardware, overflow_bit, 0, &thread, cidx );
00739     }
00740     else {
00741 #ifdef DEBUG_BGQ
00742         printf("OVERFLOW_NONE\n");
00743 #endif
00744         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);
00745     }
00746 }
00747 
00748 
00749 /*
00750  * Set Overflow
00751  *
00752  * This is commented out in BG/L/P - need to explore and complete...
00753  * However, with true 64-bit counters in BG/Q and all counters for PAPI
00754  * always starting from a true zero (we don't allow write...), the possibility
00755  * for overflow is remote at best...
00756  */
00757 int
00758 _bgq_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
00759 {
00760 #ifdef DEBUG_BGQ
00761     printf("BEGIN _bgq_set_overflow\n");
00762 #endif
00763     hwd_control_state_t * this_state = ( hwd_control_state_t * ) ESI->ctl_state;
00764     int retval;
00765     int evt_idx;
00766     
00767     /*
00768      * In case an BGPM eventGroup HAS BEEN applied or attached before
00769      * overflow is set, delete the eventGroup and create an new empty one,
00770      * and rebuild as it was prior to deletion
00771      */
00772 #ifdef DEBUG_BGQ
00773     printf( "_bgq_set_overflow: bgpm_eventset_applied = %d\n",
00774             this_state->bgpm_eventset_applied );
00775 #endif  
00776     if ( 1 == this_state->bgpm_eventset_applied ) {
00777         _common_deleteRecreate( &this_state->EventGroup );
00778         _common_rebuildEventgroup( this_state->count,
00779                                    this_state->EventGroup_local,
00780                                    &this_state->EventGroup );
00781         
00782         /* set BGPM eventGroup flag back to NOT applied yet (0) 
00783          * because the eventGroup has been recreated from scratch */
00784         this_state->bgpm_eventset_applied = 0;
00785     }
00786     
00787     
00788     evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
00789     //evt_id = ( ESI->NativeInfoArray[EventIndex].ni_event & PAPI_NATIVE_AND_MASK ) + 1;
00790     SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
00791             evt_idx, EventIndex, threshold );
00792 #ifdef DEBUG_BGQ
00793     printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
00794             evt_idx, EventIndex, threshold );
00795 #endif
00796     
00797     /* If this counter isn't set to overflow, it's an error */
00798     if ( threshold == 0 ) {
00799         /* Remove the signal handler */
00800         retval = _papi_hwi_stop_signal( _bgq_vectors.cmp_info.hardware_intr_sig );
00801         if ( retval != PAPI_OK )
00802             return ( retval );
00803     }
00804     else {
00805         this_state->overflow = 1;
00806         this_state->overflow_threshold = threshold;
00807         this_state->overflow_EventIndex = evt_idx;
00808     
00809 #ifdef DEBUG_BGQ
00810         printf( "_bgq_set_overflow: Enable the signal handler\n" );
00811 #endif      
00812         /* Enable the signal handler */
00813         retval = _papi_hwi_start_signal( _bgq_vectors.cmp_info.hardware_intr_sig, 
00814                                          NEED_CONTEXT, 
00815                                          _bgq_vectors.cmp_info.CmpIdx );
00816         if ( retval != PAPI_OK )
00817             return ( retval );
00818 
00819         
00820         _common_set_overflow_BGPM( this_state->EventGroup, 
00821                                    this_state->overflow_EventIndex, 
00822                                    this_state->overflow_threshold,
00823                                    user_signal_handler );
00824     }
00825 
00826     return ( PAPI_OK );
00827 }
00828 
00829 
00830 /*
00831  * Set Profile
00832  *
00833  * Same as for BG/L/P, routine not used and returns error
00834  */
00835 int
00836 _bgq_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold )
00837 {
00838 #ifdef DEBUG_BGQ
00839     printf("BEGIN _bgq_set_profile\n");
00840 #endif
00841     
00842     ( void ) ESI;
00843     ( void ) EventIndex;
00844     ( void ) threshold;
00845     
00846     return PAPI_ECMP;
00847 }
00848 
00849 /*
00850  * Stop Profiling
00851  *
00852  * Same as for BG/L/P...
00853  */
00854 int
00855 _bgq_stop_profiling( ThreadInfo_t * master, EventSetInfo_t * ESI )
00856 {
00857 #ifdef DEBUG_BGQ
00858     printf("BEGIN _bgq_stop_profiling\n");
00859 #endif
00860     
00861     ( void ) master;
00862     ( void ) ESI;
00863     
00864     return ( PAPI_OK );
00865 }
00866 
00867 /*
00868  * PAPI Control
00869  *
00870  * Same as for BG/L/P - initialize the domain
00871  */
00872 int
00873 _bgq_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
00874 {
00875 #ifdef DEBUG_BGQ
00876     printf( "_bgq_ctl\n" );
00877 #endif
00878     ( void ) ctx;
00879     int retval;
00880     
00881     switch ( code ) {
00882         case PAPI_MULTIPLEX:
00883         {
00884             hwd_control_state_t * bgq_state = ( ( hwd_control_state_t * ) option->multiplex.ESI->ctl_state );
00885             bgq_state->muxOn = 1;
00886             retval = _bgq_multiplex( bgq_state );
00887             return ( retval );
00888         }
00889         default:
00890             return ( PAPI_OK );
00891     }
00892 }
00893 
00894 /*
00895  * Get Real Micro-seconds
00896  */
00897 long long
00898 _bgq_get_real_usec( void )
00899 {
00900 #ifdef DEBUG_BGQ
00901     printf( "_bgq_get_real_usec\n" );
00902 #endif
00903     
00904     /*
00905      * NOTE:  _papi_hwi_system_info.hw_info.mhz is really a representation of unit of time per cycle.
00906      *        On BG/P, it's value is 8.5e-4.  Therefore, to get cycles per sec, we have to multiply
00907      *        by 1.0e12.  To then convert to usec, we have to divide by 1.0e-3.
00908      */
00909     return ( ( long long ) ( ( ( float ) get_cycles(  ) ) /
00910                              ( ( _papi_hwi_system_info.hw_info.cpu_max_mhz ) ) ) );
00911 
00912 }
00913 
00914 /*
00915  * Get Real Cycles
00916  *
00917  * Same for BG/L/P, using native function...
00918  */
00919 long long
00920 _bgq_get_real_cycles( void )
00921 {
00922 #ifdef DEBUG_BGQ
00923     printf( "_bgq_get_real_cycles\n" );
00924 #endif
00925 
00926     return ( ( long long ) get_cycles(  ) );
00927 
00928 }
00929 
00930 /*
00931  * Get Virtual Micro-seconds
00932  *
00933  * Same calc as for BG/L/P, returns real usec...
00934  */
00935 long long
00936 _bgq_get_virt_usec( void )
00937 {
00938 #ifdef DEBUG_BGQ
00939     printf( "_bgq_get_virt_usec\n" );
00940 #endif
00941     
00942     return _bgq_get_real_usec(  );
00943 }
00944 
00945 /*
00946  * Get Virtual Cycles
00947  *
00948  * Same calc as for BG/L/P, returns real cycles...
00949  */
00950 long long
00951 _bgq_get_virt_cycles( void )
00952 {
00953 #ifdef DEBUG_BGQ
00954     printf( "_bgq_get_virt_cycles\n" );
00955 #endif
00956     
00957     return _bgq_get_real_cycles(  );
00958 }
00959 
00960 /*
00961  * Component setup and shutdown
00962  *
00963  * Initialize hardware counters, setup the function vector table
00964  * and get hardware information, this routine is called when the
00965  * PAPI process is initialized (IE PAPI_library_init)
00966  */
00967 int
00968 _bgq_init_component( int cidx )
00969 {   
00970 #ifdef DEBUG_BGQ
00971     printf("_bgq_init_substrate\n");
00972     //printf("_bgq_init_substrate: 1. BGPM_INITIALIZED = %d \n", BGPM_INITIALIZED);
00973 #endif
00974     int retval;
00975     int i;
00976         
00977     /* allocate the opcode event structure */
00978     GenericEvent = calloc( OPCODE_EVENT_CHUNK, sizeof( struct bgq_generic_events_t ) );
00979     if ( NULL == GenericEvent ) {
00980         return PAPI_ENOMEM;
00981     }
00982     
00983     /* init opcode event stuff */
00984     allocated_opcode_events = OPCODE_EVENT_CHUNK;
00985     num_opcode_events = 0;
00986         
00987     _bgq_vectors.cmp_info.CmpIdx = cidx;
00988 
00989     /*
00990      * Fill in what we can of the papi_system_info
00991      */
00992     SUBDBG( "Before _bgq_get_system_info()...\n" );
00993     retval = _bgq_get_system_info( &_papi_hwi_system_info );
00994     SUBDBG( "After _bgq_get_system_info(), retval=%d...\n", retval );
00995     if ( retval != PAPI_OK )
00996         return ( retval );
00997 
00998     /*
00999      * Setup memory info
01000      */
01001 
01002     SUBDBG( "Before _bgq_get_memory_info...\n" );
01003     retval = _bgq_get_memory_info( &_papi_hwi_system_info.hw_info,
01004                                   ( int ) _papi_hwi_system_info.hw_info.
01005                                   model );
01006     SUBDBG( "After _bgq_get_memory_info, retval=%d...\n", retval );
01007     if ( retval )
01008         return ( retval );
01009 #if 1
01010     /* Setup Locks */
01011     for ( i = 0; i < PAPI_MAX_LOCK; i++ )
01012         thdLocks[i] = 0;  // MUTEX_OPEN
01013 #else
01014     for( i = 0; i < PAPI_MAX_LOCK; i++ ) {
01015         pthread_mutex_init( &thdLocks[i], NULL );
01016     }
01017 #endif
01018     
01019     /* Setup presets */
01020     retval = _papi_load_preset_table( "BGQ", 0, cidx );
01021     if ( retval ) {
01022         return retval;
01023     }   
01024     
01025     
01026     return ( PAPI_OK );
01027 }
01028 
01029 
01030 /*************************************/
01031 /* CODE TO SUPPORT OPAQUE NATIVE MAP */
01032 /*************************************/
01033 
01034 /*
01035  * Event Name to Native Code
01036  */
01037 int
01038 _bgq_ntv_name_to_code( char *name, unsigned int *event_code )
01039 {
01040 #ifdef DEBUG_BGQ
01041     printf( "_bgq_ntv_name_to_code\n" );
01042 #endif
01043     int ret;
01044 #ifdef DEBUG_BGQ
01045     printf( "name = ===%s===\n", name );
01046 #endif  
01047 
01048     /* Treat events differently if BGPM Opcodes are used */
01049     /* Opcode group selection values are "OR"ed together to create a desired 
01050      mask of instruction group events to accumulate in the same counter */  
01051     if ( 0 == strncmp( name, "PEVT_INST_XU_GRP_MASK", strlen( "PEVT_INST_XU_GRP_MASK" ) ) ||
01052          0 == strncmp( name, "PEVT_INST_QFPU_GRP_MASK", strlen( "PEVT_INST_QFPU_GRP_MASK" ) ) ) {
01053 
01054         char *pcolon;
01055         pcolon = strchr( name, ':' );
01056         
01057         // Found colon separator
01058         if ( pcolon != NULL ) {
01059             int mask_len = pcolon - name;
01060             strncpy( GenericEvent[num_opcode_events].mask, name,  mask_len  );
01061             strncpy( GenericEvent[num_opcode_events].opcode, pcolon+1, strlen(name) - 1 - mask_len );
01062             /* opcode_mask needs to be 'uint64_t',
01063                hence we use strtoull() which returns an 'unsigned long long int' */
01064             GenericEvent[num_opcode_events].opcode_mask = strtoull( GenericEvent[num_opcode_events].opcode, (char **)NULL, 16 );
01065             GenericEvent[num_opcode_events].idx = OPCODE_BUF + num_opcode_events;
01066             /* Return event id matching the generic XU/QFPU event string */
01067             GenericEvent[num_opcode_events].eventId = Bgpm_GetEventIdFromLabel( GenericEvent[num_opcode_events].mask );
01068             if ( GenericEvent[num_opcode_events].eventId <= 0 ) {
01069 #ifdef DEBUG_BGPM
01070                 printf ("Error: ret value is %d for BGPM API function '%s'.\n",
01071                         ret, "Bgpm_GetEventIdFromLabel" );
01072 #endif
01073                 return PAPI_ENOEVNT;
01074             }
01075             
01076             *event_code = GenericEvent[num_opcode_events].idx;
01077             
01078             num_opcode_events++;
01079             
01080             /* If there are too many opcode events than allocated, then allocate more room */
01081             if( num_opcode_events >= allocated_opcode_events ) {
01082                 
01083                 SUBDBG("Allocating more room for BGPM opcode events (%d %ld)\n",
01084                        ( allocated_opcode_events + NATIVE_OPCODE_CHUNK ),
01085                        ( long )sizeof( struct bgq_generic_events_t ) *
01086                        ( allocated_opcode_events + NATIVE_OPCODE_CHUNK ) );
01087                 
01088                 GenericEvent = realloc( GenericEvent, sizeof( struct bgq_generic_events_t ) *
01089                                        ( allocated_opcode_events + OPCODE_EVENT_CHUNK ) );
01090                 if ( NULL == GenericEvent ) {
01091                     return PAPI_ENOMEM;
01092                 }
01093                 allocated_opcode_events += OPCODE_EVENT_CHUNK;
01094             }
01095         }
01096         else {
01097             SUBDBG( "Error: Found a generic BGPM event mask without opcode string\n" );
01098             return PAPI_ENOEVNT;
01099         }
01100         
01101         
01102 #ifdef DEBUG_BGQ
01103         printf(_AT_ " _bgq_ntv_name_to_code: GenericEvent no. %d: \n", num_opcode_events-1 );
01104         printf( "idx         = %d\n", GenericEvent[num_opcode_events-1].idx);
01105         printf( "eventId     = %d\n", GenericEvent[num_opcode_events-1].eventId);
01106         printf( "mask        = %s\n", GenericEvent[num_opcode_events-1].mask);
01107         printf( "opcode      = %s\n", GenericEvent[num_opcode_events-1].opcode);
01108         printf( "opcode_mask = %" PRIX64 " (%" PRIu64 ")\n", GenericEvent[num_opcode_events-1].opcode_mask,
01109                GenericEvent[num_opcode_events-1].opcode_mask );
01110 #endif
01111     }
01112     else {
01113         /* Return event id matching a given event label string */
01114         ret = Bgpm_GetEventIdFromLabel ( name );
01115         
01116         if ( ret <= 0 ) {
01117 #ifdef DEBUG_BGPM
01118             printf ("Error: ret value is %d for BGPM API function '%s'.\n",
01119                     ret, "Bgpm_GetEventIdFromLabel" );
01120 #endif
01121             return PAPI_ENOEVNT;
01122         }
01123         else if ( ret > BGQ_PUNIT_MAX_COUNTERS ) // not a PUnit event
01124             return PAPI_ENOEVNT;
01125         else
01126             *event_code = ( ret - 1 );      
01127     }
01128     
01129     return PAPI_OK;
01130 }
01131 
01132 
01133 /*
01134  * Native Code to Event Name
01135  *
01136  * Given a native event code, returns the short text label
01137  */
01138 int
01139 _bgq_ntv_code_to_name( unsigned int EventCode, char *name, int len )
01140 {   
01141 #ifdef DEBUG_BGQ    
01142     printf( "_bgq_ntv_code_to_name\n" );
01143 #endif
01144     int index = ( EventCode & PAPI_NATIVE_AND_MASK ) + 1;
01145     
01146     if ( index >= MAX_COUNTERS )
01147         return PAPI_ENOEVNT;
01148             
01149     strncpy( name, Bgpm_GetEventIdLabel( index ), len );
01150     
01151     if ( name == NULL ) {
01152 #ifdef DEBUG_BGPM
01153         printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" );
01154 #endif
01155         return PAPI_ENOEVNT;
01156     }
01157 #ifdef DEBUG_BGQ
01158     printf( "name = ===%s===\n", name );
01159 #endif  
01160     
01161     return ( PAPI_OK );
01162 }
01163 
01164 /*
01165  * Native Code to Event Description
01166  *
01167  * Given a native event code, returns the longer native event description
01168  */
01169 int
01170 _bgq_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
01171 {   
01172 #ifdef DEBUG_BGQ
01173     printf( "_bgq_ntv_code_to_descr\n" );
01174 #endif
01175     int retval;
01176     int index = ( EventCode & PAPI_NATIVE_AND_MASK ) + 1;
01177 
01178     retval = Bgpm_GetLongDesc( index, name, &len );
01179     CHECK_BGPM_ERROR( retval, "Bgpm_GetLongDesc" );                      
01180 
01181     return ( PAPI_OK );
01182 }
01183 
01184 /*
01185  * Native Code to Bit Configuration
01186  *
01187  * Given a native event code, assigns the native event's
01188  * information to a given pointer.
01189  * NOTE: The info must be COPIED to location addressed by
01190  *       the provided pointer, not just referenced!
01191  * NOTE: For BG/Q, the bit configuration is not needed,
01192  *       as the native SPI is used to configure events.
01193  */
01194 int
01195 _bgq_ntv_code_to_bits( unsigned int EventCode, hwd_register_t * bits )
01196 {
01197 #ifdef DEBUG_BGQ
01198     printf( "_bgq_ntv_code_to_bits\n" );
01199 #endif
01200     
01201     ( void ) EventCode;
01202     ( void ) bits;
01203     
01204     return ( PAPI_OK );
01205 }
01206 
01207 /*
01208  * Native ENUM Events
01209  *
01210  */
01211 int
01212 _bgq_ntv_enum_events( unsigned int *EventCode, int modifier )
01213 {
01214 #ifdef DEBUG_BGQ
01215     printf( "_bgq_ntv_enum_events\n" );
01216 #endif
01217     
01218     switch ( modifier ) {
01219         case PAPI_ENUM_FIRST:
01220             *EventCode = PAPI_NATIVE_MASK;
01221             
01222             return ( PAPI_OK );
01223             break;
01224             
01225         case PAPI_ENUM_EVENTS:
01226         {
01227             int index = ( *EventCode & PAPI_NATIVE_AND_MASK ) + 1;
01228             
01229             if ( index < BGQ_PUNIT_MAX_COUNTERS ) {
01230                 *EventCode = *EventCode + 1;
01231                 return ( PAPI_OK );
01232             } else
01233                 return ( PAPI_ENOEVNT );
01234             
01235             break;
01236         }
01237         default:
01238             return ( PAPI_EINVAL );
01239     }
01240     
01241     return ( PAPI_EINVAL ); 
01242 }
01243 
01244 
01245 int 
01246 _papi_hwi_init_os(void) {
01247     
01248     struct utsname uname_buffer;
01249     
01250     /* Get the kernel info */
01251     uname(&uname_buffer);
01252     
01253     strncpy(_papi_os_info.name,uname_buffer.sysname,PAPI_MAX_STR_LEN);
01254     
01255     strncpy(_papi_os_info.version,uname_buffer.release,PAPI_MAX_STR_LEN);
01256     
01257     _papi_os_info.itimer_sig = PAPI_INT_MPX_SIGNAL;
01258     _papi_os_info.itimer_num = PAPI_INT_ITIMER;
01259     _papi_os_info.itimer_res_ns = 1;
01260     
01261     return PAPI_OK;
01262 }
01263 
01264 
01265 /*
01266  * PAPI Vector Table for BG/Q
01267  */
01268 papi_vector_t _bgq_vectors = {
01269     .cmp_info = {
01270                  /* Default component information (unspecified values are initialized to 0) */
01271                  .name = "linux-bgq",
01272                  .short_name = "bgq",
01273                  .description = "Blue Gene/Q component",
01274                  .num_cntrs = BGQ_PUNIT_MAX_COUNTERS,
01275                  .num_mpx_cntrs = BGQ_PUNIT_MAX_COUNTERS,
01276                  .default_domain = PAPI_DOM_USER,
01277                  .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
01278                  .default_granularity = PAPI_GRN_THR,
01279                  .available_granularities = PAPI_GRN_THR,
01280                  .hardware_intr_sig = PAPI_INT_SIGNAL,
01281                  .hardware_intr = 1,
01282                  .kernel_multiplex = 1,
01283         
01284                  /* component specific cmp_info initializations */
01285                  .fast_real_timer = 1,
01286                  .fast_virtual_timer = 0,
01287                  }
01288     ,
01289 
01290     /* Sizes of framework-opaque component-private structures */
01291     .size = {
01292              .context = sizeof ( hwd_context_t ),
01293              .control_state = sizeof ( hwd_control_state_t ),
01294              .reg_value = sizeof ( hwd_register_t ),
01295              .reg_alloc = sizeof ( hwd_reg_alloc_t ),
01296              }
01297     ,
01298     /* Function pointers in this component */
01299 //   .get_overflow_address =
01300     .start = _bgq_start,
01301     .stop = _bgq_stop,
01302     .read = _bgq_read,
01303     .reset = _bgq_reset,
01304     .write = _bgq_write,
01305     .stop_profiling = _bgq_stop_profiling,
01306     .init_component = _bgq_init_component,
01307     .init_thread = _bgq_init,
01308     .init_control_state = _bgq_init_control_state,
01309     .update_control_state = _bgq_update_control_state,
01310     .ctl = _bgq_ctl,
01311     .set_overflow = _bgq_set_overflow,
01312     //.dispatch_timer = _bgq_dispatch_timer,
01313     .set_profile = _bgq_set_profile,
01314     .set_domain = _bgq_set_domain,
01315     .ntv_enum_events = _bgq_ntv_enum_events,
01316     .ntv_name_to_code = _bgq_ntv_name_to_code,
01317     .ntv_code_to_name = _bgq_ntv_code_to_name,
01318     .ntv_code_to_descr = _bgq_ntv_code_to_descr,
01319     .ntv_code_to_bits = _bgq_ntv_code_to_bits,
01320     .allocate_registers = _bgq_allocate_registers,
01321     .cleanup_eventset = _bgq_cleanup_eventset,
01322     .shutdown_thread = _bgq_shutdown
01323 //  .shutdown_global      =
01324 //  .user                 =
01325 };
01326 
01327 papi_os_vector_t _papi_os_vector = {
01328     .get_memory_info = _bgq_get_memory_info,
01329     .get_dmem_info = _bgq_get_dmem_info,
01330     .get_real_cycles = _bgq_get_real_cycles,
01331     .get_real_usec = _bgq_get_real_usec,
01332     .get_virt_cycles = _bgq_get_virt_cycles,
01333     .get_virt_usec = _bgq_get_virt_usec,
01334     .get_system_info = _bgq_get_system_info
01335 };
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines