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