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