linux-L2unit.c File Reference

This file has the source code for a component that enables PAPI-C to access hardware monitoring counters for BG/Q through the bgpm library. More...

Include dependency graph for linux-L2unit.c:

Go to the source code of this file.

Functions

void user_signal_handler_L2UNIT (int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext)
int L2UNIT_init_thread (hwd_context_t *ctx)
int L2UNIT_init_component (int cidx)
int L2UNIT_init_control_state (hwd_control_state_t *ptr)
int L2UNIT_start (hwd_context_t *ctx, hwd_control_state_t *ptr)
int L2UNIT_stop (hwd_context_t *ctx, hwd_control_state_t *ptr)
int L2UNIT_read (hwd_context_t *ctx, hwd_control_state_t *ptr, long_long **events, int flags)
int L2UNIT_shutdown_thread (hwd_context_t *ctx)
int L2UNIT_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold)
int L2UNIT_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int L2UNIT_cleanup_eventset (hwd_control_state_t *ctrl)
int L2UNIT_update_control_state (hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
int L2UNIT_set_domain (hwd_control_state_t *cntrl, int domain)
int L2UNIT_reset (hwd_context_t *ctx, hwd_control_state_t *ptr)
int L2UNIT_ntv_enum_events (unsigned int *EventCode, int modifier)
int L2UNIT_ntv_name_to_code (char *name, unsigned int *event_code)
int L2UNIT_ntv_code_to_name (unsigned int EventCode, char *name, int len)
int L2UNIT_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
int L2UNIT_ntv_code_to_bits (unsigned int EventCode, hwd_register_t *bits)

Variables

papi_vector_t _L2unit_vector

Detailed Description

Author:
Heike Jagode jagode@eecs.utk.edu Mods: < your name here > < your email address > BGPM / L2unit component

Tested version of bgpm (early access)

Definition in file linux-L2unit.c.


Function Documentation

int L2UNIT_cleanup_eventset ( hwd_control_state_t ctrl  ) 

Definition at line 386 of file linux-L2unit.c.

00387 {
00388 #ifdef DEBUG_BGQ
00389     printf( "L2UNIT_cleanup_eventset\n" );
00390 #endif
00391     int retval;
00392 
00393     L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ctrl;
00394     
00395     // create a new empty bgpm eventset
00396     // reason: bgpm doesn't permit to remove events from an eventset; 
00397     // hence we delete the old eventset and create a new one
00398     retval = _common_deleteRecreate( &this_state->EventGroup ); 
00399     if ( retval < 0 ) return retval;
00400 
00401     // set overflow flag to OFF (0)
00402     this_state->overflow = 0;
00403     this_state->overflow_count = 0;
00404     // set BGPM eventGroup flag back to NOT applied yet (0)
00405     this_state->bgpm_eventset_applied = 0;
00406     
00407     return ( PAPI_OK );
00408 }

Here is the call graph for this function:

int L2UNIT_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)

Definition at line 368 of file linux-L2unit.c.

00369 {
00370 #ifdef DEBUG_BGQ
00371     printf( "L2UNIT_ctl\n" );
00372 #endif
00373     
00374     ( void ) ctx;
00375     ( void ) code;
00376     ( void ) option;
00377     return ( PAPI_OK );
00378 }

int L2UNIT_init_component ( int  cidx  ) 

Definition at line 52 of file linux-L2unit.c.

00053 { 
00054 #ifdef DEBUG_BGQ
00055     printf( "L2UNIT_init_component\n" );
00056 #endif
00057     
00058     _L2unit_vector.cmp_info.CmpIdx = cidx;
00059 #ifdef DEBUG_BGQ
00060     printf( "L2UNIT_init_component cidx = %d\n", cidx );
00061 #endif
00062     
00063     return ( PAPI_OK );
00064 }

int L2UNIT_init_control_state ( hwd_control_state_t ptr  ) 

Definition at line 72 of file linux-L2unit.c.

00073 {
00074 #ifdef DEBUG_BGQ
00075     printf( "L2UNIT_init_control_state\n" );
00076 #endif
00077     int retval;
00078 
00079     L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
00080     
00081     this_state->EventGroup = Bgpm_CreateEventSet();
00082     retval = _check_BGPM_error( this_state->EventGroup, "Bgpm_CreateEventSet" );
00083     if ( retval < 0 ) return retval;
00084 
00085     // initialize overflow flag to OFF (0)
00086     this_state->overflow = 0;
00087     this_state->overflow_count = 0;
00088     // initialized BGPM eventGroup flag to NOT applied yet (0)
00089     this_state->bgpm_eventset_applied = 0;
00090 
00091     return PAPI_OK;
00092 }

Here is the call graph for this function:

int L2UNIT_init_thread ( hwd_context_t ctx  ) 

Definition at line 36 of file linux-L2unit.c.

00037 {
00038 #ifdef DEBUG_BGQ
00039     printf( "L2UNIT_init_thread\n" );
00040 #endif
00041     
00042     ( void ) ctx;
00043     return PAPI_OK;
00044 }

int L2UNIT_ntv_code_to_bits ( unsigned int  EventCode,
hwd_register_t bits 
)

Definition at line 659 of file linux-L2unit.c.

00660 {
00661 #ifdef DEBUG_BGQ
00662     printf( "L2UNIT_ntv_code_to_bits\n" );
00663 #endif
00664     ( void ) EventCode;
00665     ( void ) bits;
00666     return ( PAPI_OK );
00667 }

int L2UNIT_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 638 of file linux-L2unit.c.

00639 {
00640 #ifdef DEBUG_BGQ
00641     //printf( "L2UNIT_ntv_code_to_descr\n" );
00642 #endif
00643     int retval, index;
00644     
00645     index = ( EventCode ) + OFFSET;
00646     
00647     retval = Bgpm_GetLongDesc( index, name, &len );
00648     retval = _check_BGPM_error( retval, "Bgpm_GetLongDesc" );                        
00649     if ( retval < 0 ) return retval;
00650 
00651     return ( PAPI_OK );
00652 }

Here is the call graph for this function:

int L2UNIT_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 609 of file linux-L2unit.c.

00610 {
00611 #ifdef DEBUG_BGQ
00612     //printf( "L2UNIT_ntv_code_to_name\n" );
00613 #endif
00614     int index;
00615     
00616     index = ( EventCode ) + OFFSET;
00617 
00618     if ( index >= MAX_COUNTERS )
00619         return PAPI_ENOEVNT;
00620 
00621     strncpy( name, Bgpm_GetEventIdLabel( index ), len );
00622     
00623     if ( name == NULL ) {
00624 #ifdef DEBUG_BGPM
00625         printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" );
00626 #endif
00627         return PAPI_ENOEVNT;
00628     }
00629     
00630     return ( PAPI_OK );
00631 }

int L2UNIT_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

Definition at line 543 of file linux-L2unit.c.

00544 {
00545 #ifdef DEBUG_BGQ
00546     //printf( "L2UNIT_ntv_enum_events, EventCode = %#x\n", *EventCode );
00547 #endif
00548 
00549     switch ( modifier ) {
00550     case PAPI_ENUM_FIRST:
00551         *EventCode = 0;
00552 
00553         return ( PAPI_OK );
00554         break;
00555 
00556     case PAPI_ENUM_EVENTS:
00557     {
00558         int index = ( *EventCode ) + OFFSET;
00559 
00560         if ( index < L2UNIT_MAX_EVENTS ) {
00561             *EventCode = *EventCode + 1;
00562             return ( PAPI_OK );
00563         } else
00564             return ( PAPI_ENOEVNT );
00565 
00566         break;
00567     }
00568     default:
00569         return ( PAPI_EINVAL );
00570     }
00571     return ( PAPI_EINVAL );
00572 }

int L2UNIT_ntv_name_to_code ( char *  name,
unsigned int *  event_code 
)

Definition at line 579 of file linux-L2unit.c.

00580 {
00581 #ifdef DEBUG_BGQ
00582     printf( "L2UNIT_ntv_name_to_code\n" );
00583 #endif
00584     int ret;
00585     
00586     /* Return event id matching a given event label string */
00587     ret = Bgpm_GetEventIdFromLabel ( name );
00588     
00589     if ( ret <= 0 ) {
00590 #ifdef DEBUG_BGPM
00591         printf ("Error: ret value is %d for BGPM API function '%s'.\n",
00592                 ret, "Bgpm_GetEventIdFromLabel" );
00593 #endif
00594         return PAPI_ENOEVNT;
00595     }
00596     else if ( ret < OFFSET || ret > L2UNIT_MAX_EVENTS ) // not a L2Unit event
00597         return PAPI_ENOEVNT;
00598     else
00599         *event_code = ( ret - OFFSET );
00600 
00601     return PAPI_OK;
00602 }

int L2UNIT_read ( hwd_context_t ctx,
hwd_control_state_t ptr,
long_long **  events,
int  flags 
)

Definition at line 150 of file linux-L2unit.c.

00152 {
00153 #ifdef DEBUG_BGQ
00154     printf( "L2UNIT_read\n" );
00155 #endif
00156     ( void ) ctx;
00157     ( void ) flags;
00158     int i, numEvts;
00159     L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
00160     
00161     numEvts = Bgpm_NumEvents( this_state->EventGroup );
00162     if ( numEvts == 0 ) {
00163 #ifdef DEBUG_BGPM
00164         printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts );
00165 #endif
00166         //return ( EXIT_FAILURE );
00167     }
00168 
00169     for ( i = 0; i < numEvts; i++ )
00170         this_state->counters[i] = _common_getEventValue( i, this_state->EventGroup );
00171     
00172     *events = this_state->counters;
00173     
00174     return ( PAPI_OK );
00175 }

Here is the call graph for this function:

int L2UNIT_reset ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 514 of file linux-L2unit.c.

00515 {
00516 #ifdef DEBUG_BGQ
00517     printf( "L2UNIT_reset\n" );
00518 #endif
00519     ( void ) ctx;
00520     int retval;
00521     L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
00522 
00523     /* we can't simply call Bgpm_Reset() since PAPI doesn't have the 
00524      restriction that an EventSet has to be stopped before resetting is
00525      possible. However, BGPM does have this restriction. 
00526      Hence we need to stop, reset and start */
00527     retval = Bgpm_Stop( this_state->EventGroup );
00528     retval = _check_BGPM_error( retval, "Bgpm_Stop" );
00529     if ( retval < 0 ) return retval;
00530 
00531     retval = Bgpm_ResetStart( this_state->EventGroup );
00532     retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
00533     if ( retval < 0 ) return retval;
00534 
00535     return ( PAPI_OK );
00536 }

Here is the call graph for this function:

int L2UNIT_set_domain ( hwd_control_state_t cntrl,
int  domain 
)

Definition at line 486 of file linux-L2unit.c.

00487 {
00488 #ifdef DEBUG_BGQ
00489     printf( "L2UNIT_set_domain\n" );
00490 #endif
00491     int found = 0;
00492     ( void ) cntrl;
00493 
00494     if ( PAPI_DOM_USER & domain )
00495         found = 1;
00496 
00497     if ( PAPI_DOM_KERNEL & domain )
00498         found = 1;
00499 
00500     if ( PAPI_DOM_OTHER & domain )
00501         found = 1;
00502 
00503     if ( !found )
00504         return ( PAPI_EINVAL );
00505 
00506     return ( PAPI_OK );
00507 }

int L2UNIT_set_overflow ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
)

Definition at line 290 of file linux-L2unit.c.

00291 {
00292 #ifdef DEBUG_BGQ
00293     printf("BEGIN L2UNIT_set_overflow\n");
00294 #endif
00295     L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ESI->ctl_state;
00296     int retval;
00297     int evt_idx;
00298     
00299     /*
00300      * In case an BGPM eventGroup HAS BEEN applied or attached before
00301      * overflow is set, delete the eventGroup and create an new empty one,
00302      * and rebuild as it was prior to deletion
00303      */
00304 #ifdef DEBUG_BGQ
00305     printf( "L2UNIT_set_overflow: bgpm_eventset_applied = %d, threshold = %d\n",
00306            this_state->bgpm_eventset_applied, threshold );
00307 #endif  
00308     if ( 1 == this_state->bgpm_eventset_applied && 0 != threshold ) {
00309         retval = _common_deleteRecreate( &this_state->EventGroup );
00310         if ( retval < 0 ) return retval;
00311         retval = _common_rebuildEventgroup( this_state->count,
00312                                   this_state->EventGroup_local,
00313                                   &this_state->EventGroup );
00314         if ( retval < 0 ) return retval;
00315 
00316         /* set BGPM eventGroup flag back to NOT applied yet (0) 
00317          * because the eventGroup has been recreated from scratch */
00318         this_state->bgpm_eventset_applied = 0;
00319     }
00320         
00321     evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
00322     SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
00323            evt_idx, EventIndex, threshold );
00324 #ifdef DEBUG_BGQ
00325     printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
00326            evt_idx, EventIndex, threshold );
00327 #endif
00328     /* If this counter isn't set to overflow, it's an error */
00329     if ( threshold == 0 ) {
00330         /* Remove the signal handler */
00331         retval = _papi_hwi_stop_signal( _L2unit_vector.cmp_info.hardware_intr_sig );
00332         if ( retval != PAPI_OK )
00333             return ( retval );
00334     }
00335     else {
00336         this_state->overflow = 1;
00337         this_state->overflow_count++;
00338         this_state->overflow_list[this_state->overflow_count-1].threshold = threshold;
00339         this_state->overflow_list[this_state->overflow_count-1].EventIndex = evt_idx;
00340         
00341 #ifdef DEBUG_BGQ
00342         printf( "L2UNIT_set_overflow: Enable the signal handler\n" );
00343 #endif
00344         /* Enable the signal handler */
00345         retval = _papi_hwi_start_signal( _L2unit_vector.cmp_info.hardware_intr_sig, 
00346                                         NEED_CONTEXT, 
00347                                         _L2unit_vector.cmp_info.CmpIdx );
00348         if ( retval != PAPI_OK )
00349             return ( retval );
00350 
00351         retval = _common_set_overflow_BGPM( this_state->EventGroup,
00352                                   this_state->overflow_list[this_state->overflow_count-1].EventIndex,
00353                                   this_state->overflow_list[this_state->overflow_count-1].threshold,
00354                                   user_signal_handler_L2UNIT );
00355         if ( retval < 0 ) return retval;
00356     }
00357     
00358     return ( PAPI_OK );
00359 }

Here is the call graph for this function:

int L2UNIT_shutdown_thread ( hwd_context_t ctx  ) 

Definition at line 182 of file linux-L2unit.c.

00183 {
00184 #ifdef DEBUG_BGQ
00185     printf( "L2UNIT_shutdown_thread\n" );
00186 #endif
00187     
00188     ( void ) ctx;
00189     return ( PAPI_OK );
00190 }

int L2UNIT_start ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 99 of file linux-L2unit.c.

00100 {
00101 #ifdef DEBUG_BGQ
00102     printf( "L2UNIT_start\n" );
00103 #endif
00104     ( void ) ctx;
00105     int retval;
00106     L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
00107     
00108     retval = Bgpm_Apply( this_state->EventGroup ); 
00109     retval = _check_BGPM_error( retval, "Bgpm_Apply" );
00110     if ( retval < 0 ) return retval;
00111 
00112     // set flag to 1: BGPM eventGroup HAS BEEN applied
00113     this_state->bgpm_eventset_applied = 1;
00114 
00115     /* Bgpm_Apply() does an implicit reset; 
00116      hence no need to use Bgpm_ResetStart */
00117     retval = Bgpm_Start( this_state->EventGroup );
00118     retval = _check_BGPM_error( retval, "Bgpm_Start" );
00119     if ( retval < 0 ) return retval;
00120 
00121     return ( PAPI_OK );
00122 }

Here is the call graph for this function:

int L2UNIT_stop ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 129 of file linux-L2unit.c.

00130 {
00131 #ifdef DEBUG_BGQ
00132     printf( "L2UNIT_stop\n" );
00133 #endif
00134     ( void ) ctx;
00135     int retval;
00136     L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
00137     
00138     retval = Bgpm_Stop( this_state->EventGroup );
00139     retval = _check_BGPM_error( retval, "Bgpm_Stop" );
00140     if ( retval < 0 ) return retval;
00141 
00142     return ( PAPI_OK );
00143 }

Here is the call graph for this function:

int L2UNIT_update_control_state ( hwd_control_state_t ptr,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)

Definition at line 415 of file linux-L2unit.c.

00418 {
00419 #ifdef DEBUG_BGQ
00420     printf( "L2UNIT_update_control_state: count = %d\n", count );
00421 #endif  
00422     
00423     ( void ) ctx;
00424     int retval, index, i, k;
00425     L2UNIT_control_state_t * this_state = ( L2UNIT_control_state_t * ) ptr;
00426     
00427     // Delete and re-create BGPM eventset
00428     retval = _common_deleteRecreate( &this_state->EventGroup );
00429     if ( retval < 0 ) return retval;
00430 
00431 #ifdef DEBUG_BGQ
00432     printf( "L2UNIT_update_control_state: EventGroup=%d, overflow = %d\n",
00433            this_state->EventGroup, this_state->overflow );
00434 #endif
00435     
00436     
00437     // otherwise, add the events to the eventset
00438     for ( i = 0; i < count; i++ ) {
00439         index = ( native[i].ni_event ) + OFFSET;
00440         
00441         native[i].ni_position = i;
00442         
00443 #ifdef DEBUG_BGQ
00444         printf("L2UNIT_update_control_state: ADD event: i = %d, index = %d\n", i, index );
00445 #endif
00446         
00447         this_state->EventGroup_local[i] = index;
00448 
00449         
00450         /* Add events to the BGPM eventGroup */
00451         retval = Bgpm_AddEvent( this_state->EventGroup, index );
00452         retval = _check_BGPM_error( retval, "Bgpm_AddEvent" );
00453         if ( retval < 0 ) return retval;
00454     }
00455     
00456     // store how many events we added to an EventSet
00457     this_state->count = count;
00458 
00459     // since update_control_state trashes overflow settings, this puts things
00460     // back into balance for BGPM
00461     if ( 1 == this_state->overflow ) {
00462         for ( k = 0; k < this_state->overflow_count; k++ ) {
00463             retval = _common_set_overflow_BGPM( this_state->EventGroup,
00464                                       this_state->overflow_list[k].EventIndex,
00465                                       this_state->overflow_list[k].threshold,
00466                                       user_signal_handler_L2UNIT );
00467             if ( retval < 0 ) return retval;
00468         }
00469     }
00470     
00471     return ( PAPI_OK );
00472 }

Here is the call graph for this function:

void user_signal_handler_L2UNIT ( int  hEvtSet,
uint64_t  address,
uint64_t  ovfVector,
const ucontext_t *  pContext 
)

Definition at line 202 of file linux-L2unit.c.

00203 {
00204 #ifdef DEBUG_BGQ
00205     printf( "user_signal_handler_L2UNIT\n" );
00206 #endif
00207     ( void ) address;
00208     int retval;
00209     unsigned i;
00210     int isHardware = 1;
00211     int cidx = _L2unit_vector.cmp_info.CmpIdx;
00212     long_long overflow_bit = 0;
00213     caddr_t address1;
00214     _papi_hwi_context_t ctx;
00215     ctx.ucontext = ( hwd_ucontext_t * ) pContext;
00216     ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
00217     EventSetInfo_t *ESI;
00218     ESI = thread->running_eventset[cidx];
00219     // Get the indices of all events which have overflowed.
00220     unsigned ovfIdxs[BGPM_MAX_OVERFLOW_EVENTS];
00221     unsigned len = BGPM_MAX_OVERFLOW_EVENTS;
00222     
00223     retval = Bgpm_GetOverflowEventIndices( hEvtSet, ovfVector, ovfIdxs, &len );
00224     if ( retval < 0 ) {
00225 #ifdef DEBUG_BGPM
00226         printf ( "Error: ret value is %d for BGPM API function Bgpm_GetOverflowEventIndices.\n",
00227                  retval );
00228 #endif
00229         return;
00230     }
00231     
00232     if ( thread == NULL ) {
00233         PAPIERROR( "thread == NULL in user_signal_handler!" );
00234         return;
00235     }
00236     
00237     if ( ESI == NULL ) {
00238         PAPIERROR( "ESI == NULL in user_signal_handler!");
00239         return;
00240     }
00241     
00242     if ( ESI->overflow.flags == 0 ) {
00243         PAPIERROR( "ESI->overflow.flags == 0 in user_signal_handler!");
00244         return;
00245     }
00246     
00247     for ( i = 0; i < len; i++ ) {
00248         uint64_t hProf;
00249         Bgpm_GetEventUser1( hEvtSet, ovfIdxs[i], &hProf );
00250         if ( hProf ) {
00251             overflow_bit ^= 1 << ovfIdxs[i];
00252             break;
00253         }
00254         
00255     }
00256     
00257     if ( ESI->overflow.flags & PAPI_OVERFLOW_FORCE_SW ) {
00258 #ifdef DEBUG_BGQ
00259         printf("OVERFLOW_SOFTWARE\n");
00260 #endif
00261         address1 = GET_OVERFLOW_ADDRESS( ctx );
00262         _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, NULL, 0, 0, &thread, cidx );
00263         return;
00264     }
00265     else if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
00266 #ifdef DEBUG_BGQ
00267         printf("OVERFLOW_HARDWARE\n");
00268 #endif
00269         address1 = GET_OVERFLOW_ADDRESS( ctx );
00270         _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address1, &isHardware, overflow_bit, 0, &thread, cidx );
00271     }
00272     else {
00273 #ifdef DEBUG_BGQ
00274         printf("OVERFLOW_NONE\n");
00275 #endif
00276         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);
00277     }
00278 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 23 of file linux-L2unit.c.


Generated on 17 Nov 2016 for PAPI by  doxygen 1.6.1