linux-IOunit.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-IOunit.c:

Go to the source code of this file.

Functions

void user_signal_handler_IOUNIT (int hEvtSet, uint64_t address, uint64_t ovfVector, const ucontext_t *pContext)
int IOUNIT_init_thread (hwd_context_t *ctx)
int IOUNIT_init_component (int cidx)
int IOUNIT_init_control_state (hwd_control_state_t *ptr)
int IOUNIT_start (hwd_context_t *ctx, hwd_control_state_t *ptr)
int IOUNIT_stop (hwd_context_t *ctx, hwd_control_state_t *ptr)
int IOUNIT_read (hwd_context_t *ctx, hwd_control_state_t *ptr, long_long **events, int flags)
int IOUNIT_shutdown_thread (hwd_context_t *ctx)
int IOUNIT_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold)
int IOUNIT_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int IOUNIT_update_control_state (hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
int IOUNIT_set_domain (hwd_control_state_t *cntrl, int domain)
int IOUNIT_reset (hwd_context_t *ctx, hwd_control_state_t *ptr)
int IOUNIT_cleanup_eventset (hwd_control_state_t *ctrl)
int IOUNIT_ntv_enum_events (unsigned int *EventCode, int modifier)
int IOUNIT_ntv_name_to_code (char *name, unsigned int *event_code)
int IOUNIT_ntv_code_to_name (unsigned int EventCode, char *name, int len)
int IOUNIT_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
int IOUNIT_ntv_code_to_bits (unsigned int EventCode, hwd_register_t *bits)

Variables

papi_vector_t _IOunit_vector

Detailed Description

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

Tested version of bgpm (early access)

Definition in file linux-IOunit.c.


Function Documentation

int IOUNIT_cleanup_eventset ( hwd_control_state_t ctrl  ) 

Definition at line 471 of file linux-IOunit.c.

00472 {
00473 #ifdef DEBUG_BGQ
00474     printf( "IOUNIT_cleanup_eventset\n" );
00475 #endif
00476     int retval;
00477 
00478     IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ctrl;
00479         
00480     // create a new empty bgpm eventset
00481     // reason: bgpm doesn't permit to remove events from an eventset; 
00482     // hence we delete the old eventset and create a new one
00483     retval = _common_deleteRecreate( &this_state->EventGroup ); // HJ try to use delete() only
00484     if ( retval < 0 ) return retval;
00485 
00486     // set overflow flag to OFF (0)
00487     this_state->overflow = 0;
00488     this_state->overflow_count = 0;
00489     
00490     return ( PAPI_OK );
00491 }

Here is the call graph for this function:

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

Definition at line 332 of file linux-IOunit.c.

00333 {
00334 #ifdef DEBUG_BGQ
00335     printf( "IOUNIT_ctl\n" );
00336 #endif
00337     
00338     ( void ) ctx;
00339     ( void ) code;
00340     ( void ) option;
00341     return ( PAPI_OK );
00342 }

int IOUNIT_init_component ( int  cidx  ) 

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

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

int IOUNIT_init_control_state ( hwd_control_state_t ptr  ) 

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

00073 {
00074 #ifdef DEBUG_BGQ
00075     printf( "IOUNIT_init_control_state\n" );
00076 #endif
00077     int retval;
00078 
00079     IOUNIT_control_state_t * this_state = ( IOUNIT_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     
00089     return PAPI_OK;
00090 }

Here is the call graph for this function:

int IOUNIT_init_thread ( hwd_context_t ctx  ) 

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

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

int IOUNIT_ntv_code_to_bits ( unsigned int  EventCode,
hwd_register_t bits 
)

Definition at line 614 of file linux-IOunit.c.

00615 {
00616 #ifdef DEBUG_BGQ
00617     printf( "IOUNIT_ntv_code_to_bits\n" );
00618 #endif
00619     ( void ) EventCode;
00620     ( void ) bits;
00621     return ( PAPI_OK );
00622 }

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

Definition at line 593 of file linux-IOunit.c.

00594 {
00595 #ifdef DEBUG_BGQ
00596     //printf( "IOUNIT_ntv_code_to_descr\n" );
00597 #endif  
00598     int retval, index;
00599     
00600     index = ( EventCode ) + OFFSET;
00601     
00602     retval = Bgpm_GetLongDesc( index, name, &len );
00603     retval = _check_BGPM_error( retval, "Bgpm_GetLongDesc" );                        
00604     if ( retval < 0 ) return retval;
00605 
00606     return ( PAPI_OK );
00607 }

Here is the call graph for this function:

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

Definition at line 564 of file linux-IOunit.c.

00565 {
00566 #ifdef DEBUG_BGQ
00567     //printf( "IOUNIT_ntv_code_to_name\n" );
00568 #endif
00569     int index;
00570     
00571     index = ( EventCode ) + OFFSET;
00572 
00573     if ( index >= MAX_COUNTERS )
00574         return PAPI_ENOEVNT;
00575 
00576     strncpy( name, Bgpm_GetEventIdLabel( index ), len );
00577     
00578     if ( name == NULL ) {
00579 #ifdef DEBUG_BGPM
00580         printf ("Error: ret value is NULL for BGPM API function Bgpm_GetEventIdLabel.\n" );
00581 #endif
00582         return PAPI_ENOEVNT;
00583     }
00584     
00585     return ( PAPI_OK );
00586 }

int IOUNIT_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

Definition at line 498 of file linux-IOunit.c.

00499 {
00500 #ifdef DEBUG_BGQ
00501     //printf( "IOUNIT_ntv_enum_events\n" );
00502 #endif
00503 
00504     switch ( modifier ) {
00505     case PAPI_ENUM_FIRST:
00506         *EventCode = 0;
00507 
00508         return ( PAPI_OK );
00509         break;
00510 
00511     case PAPI_ENUM_EVENTS:
00512     {
00513         int index = ( *EventCode ) + OFFSET;
00514 
00515         if ( index < IOUNIT_MAX_EVENTS ) {
00516             *EventCode = *EventCode + 1;
00517             return ( PAPI_OK );
00518         } else
00519             return ( PAPI_ENOEVNT );
00520 
00521         break;
00522     }
00523     default:
00524         return ( PAPI_EINVAL );
00525     }
00526     return ( PAPI_EINVAL );
00527 }

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

Definition at line 534 of file linux-IOunit.c.

00535 {
00536 #ifdef DEBUG_BGQ
00537     printf( "IOUNIT_ntv_name_to_code\n" );
00538 #endif
00539     int ret;
00540     
00541     /* Return event id matching a given event label string */
00542     ret = Bgpm_GetEventIdFromLabel ( name );
00543     
00544     if ( ret <= 0 ) {
00545 #ifdef DEBUG_BGPM
00546         printf ("Error: ret value is %d for BGPM API function '%s'.\n",
00547                 ret, "Bgpm_GetEventIdFromLabel" );
00548 #endif
00549         return PAPI_ENOEVNT;
00550     }
00551     else if ( ret < OFFSET || ret > IOUNIT_MAX_EVENTS ) // not an IOUnit event
00552         return PAPI_ENOEVNT;
00553     else
00554         *event_code = ( ret - OFFSET ) ;
00555     
00556     return PAPI_OK;
00557 }

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

Definition at line 139 of file linux-IOunit.c.

00141 {
00142 #ifdef DEBUG_BGQ
00143     printf( "IOUNIT_read\n" );
00144 #endif
00145     ( void ) ctx;
00146     ( void ) flags;
00147     int i, numEvts;
00148     IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
00149 
00150     numEvts = Bgpm_NumEvents( this_state->EventGroup );
00151     if ( numEvts == 0 ) {
00152 #ifdef DEBUG_BGPM
00153         printf ("Error: ret value is %d for BGPM API function Bgpm_NumEvents.\n", numEvts );
00154 #endif
00155         //return ( EXIT_FAILURE );
00156     }
00157         
00158     for ( i = 0; i < numEvts; i++ )
00159         this_state->counts[i] = _common_getEventValue( i, this_state->EventGroup );
00160 
00161     *events = this_state->counts;
00162     
00163     return ( PAPI_OK );
00164 }

Here is the call graph for this function:

int IOUNIT_reset ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 440 of file linux-IOunit.c.

00441 {
00442 #ifdef DEBUG_BGQ
00443     printf( "IOUNIT_reset\n" );
00444 #endif
00445     ( void ) ctx;
00446     int retval;
00447     IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
00448 
00449     /* we can't simply call Bgpm_Reset() since PAPI doesn't have the 
00450      restriction that an EventSet has to be stopped before resetting is
00451      possible. However, BGPM does have this restriction. 
00452      Hence we need to stop, reset and start */
00453     retval = Bgpm_Stop( this_state->EventGroup );
00454     retval = _check_BGPM_error( retval, "Bgpm_Stop" );
00455     if ( retval < 0 ) return retval;
00456 
00457     retval = Bgpm_ResetStart( this_state->EventGroup );
00458     retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
00459     if ( retval < 0 ) return retval;
00460 
00461     return ( PAPI_OK );
00462 }

Here is the call graph for this function:

int IOUNIT_set_domain ( hwd_control_state_t cntrl,
int  domain 
)

Definition at line 412 of file linux-IOunit.c.

00413 {
00414 #ifdef DEBUG_BGQ
00415     printf( "IOUNIT_set_domain\n" );
00416 #endif
00417     int found = 0;
00418     ( void ) cntrl;
00419 
00420     if ( PAPI_DOM_USER & domain )
00421         found = 1;
00422 
00423     if ( PAPI_DOM_KERNEL & domain )
00424         found = 1;
00425 
00426     if ( PAPI_DOM_OTHER & domain )
00427         found = 1;
00428 
00429     if ( !found )
00430         return ( PAPI_EINVAL );
00431 
00432     return ( PAPI_OK );
00433 }

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

Definition at line 277 of file linux-IOunit.c.

00278 {
00279 #ifdef DEBUG_BGQ
00280     printf("BEGIN IOUNIT_set_overflow\n");
00281 #endif
00282     IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ESI->ctl_state;
00283     int retval;
00284     int evt_idx;
00285         
00286     evt_idx = ESI->EventInfoArray[EventIndex].pos[0];
00287     SUBDBG( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
00288            evt_idx, EventIndex, threshold );
00289 #ifdef DEBUG_BGQ
00290     printf( "Hardware counter %d (vs %d) used in overflow, threshold %d\n",
00291            evt_idx, EventIndex, threshold );
00292 #endif
00293     /* If this counter isn't set to overflow, it's an error */
00294     if ( threshold == 0 ) {
00295         /* Remove the signal handler */
00296         retval = _papi_hwi_stop_signal( _IOunit_vector.cmp_info.hardware_intr_sig );
00297         if ( retval != PAPI_OK )
00298             return ( retval );
00299     }
00300     else {
00301         this_state->overflow = 1;
00302         this_state->overflow_count++;
00303         this_state->overflow_list[this_state->overflow_count-1].threshold = threshold;
00304         this_state->overflow_list[this_state->overflow_count-1].EventIndex = evt_idx;
00305         
00306 #ifdef DEBUG_BGQ
00307         printf( "IOUNIT_set_overflow: Enable the signal handler\n" );
00308 #endif
00309         /* Enable the signal handler */
00310         retval = _papi_hwi_start_signal( _IOunit_vector.cmp_info.hardware_intr_sig, 
00311                                         NEED_CONTEXT, 
00312                                         _IOunit_vector.cmp_info.CmpIdx );
00313         if ( retval != PAPI_OK )
00314             return ( retval );
00315 
00316         retval = _common_set_overflow_BGPM( this_state->EventGroup,
00317                                   this_state->overflow_list[this_state->overflow_count-1].EventIndex,
00318                                   this_state->overflow_list[this_state->overflow_count-1].threshold,
00319                                   user_signal_handler_IOUNIT );
00320         if ( retval < 0 ) return retval;
00321     }
00322     
00323     return ( PAPI_OK );
00324 }

Here is the call graph for this function:

int IOUNIT_shutdown_thread ( hwd_context_t ctx  ) 

Definition at line 171 of file linux-IOunit.c.

00172 {
00173 #ifdef DEBUG_BGQ
00174     printf( "IOUNIT_shutdown_thread\n" );
00175 #endif
00176     
00177     ( void ) ctx;
00178     return ( PAPI_OK );
00179 }

int IOUNIT_start ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 97 of file linux-IOunit.c.

00098 {
00099 #ifdef DEBUG_BGQ
00100     printf( "IOUNIT_start\n" );
00101 #endif
00102     ( void ) ctx;
00103     int retval;
00104     IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
00105     
00106     retval = Bgpm_ResetStart( this_state->EventGroup );
00107     retval = _check_BGPM_error( retval, "Bgpm_ResetStart" );
00108     if ( retval < 0 ) return retval;
00109 
00110     return ( PAPI_OK );
00111 }

Here is the call graph for this function:

int IOUNIT_stop ( hwd_context_t ctx,
hwd_control_state_t ptr 
)

Definition at line 118 of file linux-IOunit.c.

00119 {
00120 #ifdef DEBUG_BGQ
00121     printf( "IOUNIT_stop\n" );
00122 #endif
00123     ( void ) ctx;
00124     int retval;
00125     IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
00126     
00127     retval = Bgpm_Stop( this_state->EventGroup );
00128     retval = _check_BGPM_error( retval, "Bgpm_Stop" );
00129     if ( retval < 0 ) return retval;
00130 
00131     return ( PAPI_OK );
00132 }

Here is the call graph for this function:

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

Definition at line 349 of file linux-IOunit.c.

00352 {
00353 #ifdef DEBUG_BGQ
00354     printf( "IOUNIT_update_control_state: count = %d\n", count );
00355 #endif
00356     ( void ) ctx;
00357     int retval, index, i, k;
00358     IOUNIT_control_state_t * this_state = ( IOUNIT_control_state_t * ) ptr;
00359     
00360     // Delete and re-create BGPM eventset
00361     retval = _common_deleteRecreate( &this_state->EventGroup );
00362     if ( retval < 0 ) return retval;
00363 
00364 #ifdef DEBUG_BGQ
00365     printf( "IOUNIT_update_control_state: EventGroup=%d, overflow = %d\n",
00366            this_state->EventGroup, this_state->overflow );
00367 #endif
00368         
00369     // otherwise, add the events to the eventset
00370     for ( i = 0; i < count; i++ ) {
00371         index = ( native[i].ni_event ) + OFFSET;
00372         
00373         native[i].ni_position = i;
00374 
00375 #ifdef DEBUG_BGQ
00376         printf("IOUNIT_update_control_state: ADD event: i = %d, index = %d\n", i, index );
00377 #endif
00378                 
00379         /* Add events to the BGPM eventGroup */
00380         retval = Bgpm_AddEvent( this_state->EventGroup, index );
00381         retval = _check_BGPM_error( retval, "Bgpm_AddEvent" );
00382         if ( retval < 0 ) return retval;
00383     }
00384 
00385     // since update_control_state trashes overflow settings, this puts things
00386     // back into balance for BGPM
00387     if ( 1 == this_state->overflow ) {
00388         for ( k = 0; k < this_state->overflow_count; k++ ) {
00389             retval = _common_set_overflow_BGPM( this_state->EventGroup,
00390                                       this_state->overflow_list[k].EventIndex,
00391                                       this_state->overflow_list[k].threshold,
00392                                       user_signal_handler_IOUNIT );
00393             if ( retval < 0 ) return retval;
00394         }
00395     }
00396 
00397     return ( PAPI_OK );
00398 }

Here is the call graph for this function:

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

Definition at line 189 of file linux-IOunit.c.

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

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-IOunit.c.


Generated on 17 Nov 2016 for PAPI by  doxygen 1.6.1