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