extras.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

int _papi_hwi_stop_timer (int timer, int signal)
int _papi_hwi_start_timer (int timer, int signal, int ms)
int _papi_hwi_stop_signal (int signal)
int _papi_hwi_start_signal (int signal, int need_context, int cidx)
int _papi_hwi_initialize (DynamicArray_t **)
int _papi_hwi_dispatch_overflow_signal (void *papiContext, caddr_t address, int *, long long, int, ThreadInfo_t **master, int cidx)
void _papi_hwi_dispatch_profile (EventSetInfo_t *ESI, caddr_t address, long long over, int profile_index)

Function Documentation

int _papi_hwi_dispatch_overflow_signal ( void *  papiContext,
caddr_t  address,
int *  ,
long  long,
int  ,
ThreadInfo_t **  master,
int  cidx 
)

Definition at line 219 of file extras.c.

00223 {
00224     int retval, event_counter, i, overflow_flag, pos;
00225     int papi_index, j;
00226     int profile_index = 0;
00227     long long overflow_vector;
00228 
00229     long long temp[_papi_hwd[cidx]->cmp_info.num_cntrs], over;
00230     long long latest = 0;
00231     ThreadInfo_t *thread;
00232     EventSetInfo_t *ESI;
00233     _papi_hwi_context_t *ctx = ( _papi_hwi_context_t * ) papiContext;
00234 
00235     OVFDBG( "enter\n" );
00236 
00237     if ( *t )
00238         thread = *t;
00239     else
00240         *t = thread = _papi_hwi_lookup_thread( 0 );
00241 
00242     if ( thread != NULL ) {
00243         ESI = thread->running_eventset[cidx];
00244 
00245         if ( ( ESI == NULL ) || ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
00246             OVFDBG( "Either no eventset or eventset not set to overflow.\n" );
00247 #ifdef ANY_THREAD_GETS_SIGNAL
00248             _papi_hwi_broadcast_signal( thread->tid );
00249 #endif
00250             return ( PAPI_OK );
00251         }
00252 
00253         if ( ESI->CmpIdx != cidx )
00254             return ( PAPI_ENOCMP );
00255 
00256         if ( ESI->master != thread ) {
00257             PAPIERROR
00258                 ( "eventset->thread %#lx vs. current thread %#lx mismatch",
00259                   ESI->master, thread );
00260             return ( PAPI_EBUG );
00261         }
00262 
00263         if ( isHardware ) {
00264             if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
00265                 ESI->state |= PAPI_PAUSED;
00266                 *isHardware = 1;
00267             } else
00268                 *isHardware = 0;
00269         }
00270         /* Get the latest counter value */
00271         event_counter = ESI->overflow.event_counter;
00272 
00273         overflow_flag = 0;
00274         overflow_vector = 0;
00275 
00276         if ( !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
00277             retval = _papi_hwi_read( thread->context[cidx], ESI, ESI->sw_stop );
00278             if ( retval < PAPI_OK )
00279                 return ( retval );
00280             for ( i = 0; i < event_counter; i++ ) {
00281                 papi_index = ESI->overflow.EventIndex[i];
00282                 latest = ESI->sw_stop[papi_index];
00283                 temp[i] = -1;
00284 
00285                 if ( latest >= ( long long ) ESI->overflow.deadline[i] ) {
00286                     OVFDBG
00287                         ( "dispatch_overflow() latest %lld, deadline %lld, threshold %d\n",
00288                           latest, ESI->overflow.deadline[i],
00289                           ESI->overflow.threshold[i] );
00290                     pos = ESI->EventInfoArray[papi_index].pos[0];
00291                     overflow_vector ^= ( long long ) 1 << pos;
00292                     temp[i] = latest - ESI->overflow.deadline[i];
00293                     overflow_flag = 1;
00294                     /* adjust the deadline */
00295                     ESI->overflow.deadline[i] =
00296                         latest + ESI->overflow.threshold[i];
00297                 }
00298             }
00299         } else if ( genOverflowBit ) {
00300             /* we had assumed the overflow event can't be derived event */
00301             papi_index = ESI->overflow.EventIndex[0];
00302 
00303             /* suppose the pos is the same as the counter number
00304              * (this is not true in Itanium, but itanium doesn't 
00305              * need us to generate the overflow bit
00306              */
00307             pos = ESI->EventInfoArray[papi_index].pos[0];
00308             overflow_vector = ( long long ) 1 << pos;
00309         } else
00310             overflow_vector = overflow_bit;
00311 
00312         if ( ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) || overflow_flag ) {
00313             if ( ESI->state & PAPI_PROFILING ) {
00314                 int k = 0;
00315                 while ( overflow_vector ) {
00316                     i = ffsll( overflow_vector ) - 1;
00317                     for ( j = 0; j < event_counter; j++ ) {
00318                         papi_index = ESI->overflow.EventIndex[j];
00319                         /* This loop is here ONLY because Pentium 4 can have tagged *
00320                          * events that contain more than one counter without being  *
00321                          * derived. You've gotta scan all terms to make sure you    *
00322                          * find the one to profile. */
00323                         for ( k = 0, pos = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT && pos >= 0;
00324                               k++ ) {
00325                             pos = ESI->EventInfoArray[papi_index].pos[k];
00326                             if ( i == pos ) {
00327                                 profile_index = j;
00328                                 goto foundit;
00329                             }
00330                         }
00331                     }
00332                     if ( j == event_counter ) {
00333                         PAPIERROR
00334                             ( "BUG! overflow_vector is 0, dropping interrupt" );
00335                         return ( PAPI_EBUG );
00336                     }
00337 
00338                   foundit:
00339                     if ( ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) )
00340                         over = 0;
00341                     else
00342                         over = temp[profile_index];
00343                     _papi_hwi_dispatch_profile( ESI, address, over,
00344                                                 profile_index );
00345                     overflow_vector ^= ( long long ) 1 << i;
00346                 }
00347                 /* do not use overflow_vector after this place */
00348             } else {
00349                 ESI->overflow.handler( ESI->EventSetIndex, ( void * ) address,
00350                                        overflow_vector, ctx->ucontext );
00351             }
00352         }
00353         ESI->state &= ~( PAPI_PAUSED );
00354     }
00355 #ifdef ANY_THREAD_GETS_SIGNAL
00356     else {
00357         OVFDBG( "I haven't been noticed by PAPI before\n" );
00358         _papi_hwi_broadcast_signal( ( *_papi_hwi_thread_id_fn ) (  ) );
00359     }
00360 #endif
00361     return ( PAPI_OK );
00362 }

Here is the call graph for this function:

Here is the caller graph for this function:

void _papi_hwi_dispatch_profile ( EventSetInfo_t ESI,
caddr_t  address,
long long  over,
int  profile_index 
)

Definition at line 168 of file extras.c.

00170 {
00171     EventSetProfileInfo_t *profile = &ESI->profile;
00172     PAPI_sprofil_t *sprof;
00173     caddr_t offset = 0;
00174     caddr_t best_offset = 0;
00175     int count;
00176     int best_index = -1;
00177     int i;
00178 
00179     PRFDBG( "handled IP %p\n", pc );
00180 
00181     sprof = profile->prof[profile_index];
00182     count = profile->count[profile_index];
00183 
00184     for ( i = 0; i < count; i++ ) {
00185         offset = sprof[i].pr_off;
00186         if ( ( offset < pc ) && ( offset > best_offset ) ) {
00187             best_index = i;
00188             best_offset = offset;
00189         }
00190     }
00191 
00192     if ( best_index == -1 )
00193         best_index = 0;
00194 
00195     posix_profil( pc, &sprof[best_index], profile->flags, over,
00196                   profile->threshold[profile_index] );
00197 }

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_initialize ( DynamicArray_t **   ) 
int _papi_hwi_start_signal ( int  signal,
int  need_context,
int  cidx 
)

Definition at line 406 of file extras.c.

00407 {
00408     struct sigaction action;
00409 
00410     _papi_hwi_lock( INTERNAL_LOCK );
00411     _papi_hwi_using_signal[signal]++;
00412     if ( _papi_hwi_using_signal[signal] - 1 ) {
00413         INTDBG( "_papi_hwi_using_signal is now %d\n",
00414                 _papi_hwi_using_signal[signal] );
00415         _papi_hwi_unlock( INTERNAL_LOCK );
00416         return ( PAPI_OK );
00417     }
00418 
00419     memset( &action, 0x00, sizeof ( struct sigaction ) );
00420     action.sa_flags = SA_RESTART;
00421     action.sa_sigaction =
00422         ( void ( * )( int, siginfo_t *, void * ) ) _papi_hwd[cidx]->
00423         dispatch_timer;
00424     if ( need_context )
00425 #if (defined(_BGL) /*|| defined (__bgp__)*/)
00426         action.sa_flags |= SIGPWR;
00427 #else
00428         action.sa_flags |= SA_SIGINFO;
00429 #endif
00430 
00431     INTDBG( "installing signal handler\n" );
00432     if ( sigaction( signal, &action, NULL ) < 0 ) {
00433         PAPIERROR( "sigaction errno %d", errno );
00434         _papi_hwi_unlock( INTERNAL_LOCK );
00435         return ( PAPI_ESYS );
00436     }
00437 
00438     INTDBG( "_papi_hwi_using_signal[%d] is now %d.\n", signal,
00439             _papi_hwi_using_signal[signal] );
00440     _papi_hwi_unlock( INTERNAL_LOCK );
00441 
00442     return ( PAPI_OK );
00443 }

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_start_timer ( int  timer,
int  signal,
int  ms 
)

Definition at line 371 of file extras.c.

00372 {
00373     struct itimerval value;
00374     int us = ns / 1000;
00375 
00376     if ( us == 0 )
00377         us = 1;
00378 
00379 #ifdef ANY_THREAD_GETS_SIGNAL
00380     _papi_hwi_lock( INTERNAL_LOCK );
00381     if ( ( _papi_hwi_using_signal[signal] - 1 ) ) {
00382         INTDBG( "itimer already installed\n" );
00383         _papi_hwi_unlock( INTERNAL_LOCK );
00384         return ( PAPI_OK );
00385     }
00386     _papi_hwi_unlock( INTERNAL_LOCK );
00387 #else
00388     ( void ) signal;         /*unused */
00389 #endif
00390 
00391     value.it_interval.tv_sec = 0;
00392     value.it_interval.tv_usec = us;
00393     value.it_value.tv_sec = 0;
00394     value.it_value.tv_usec = us;
00395 
00396     INTDBG( "Installing itimer %d, with %d us interval\n", timer, us );
00397     if ( setitimer( timer, &value, NULL ) < 0 ) {
00398         PAPIERROR( "setitimer errno %d", errno );
00399         return ( PAPI_ESYS );
00400     }
00401 
00402     return ( PAPI_OK );
00403 }

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_stop_signal ( int  signal  ) 

Definition at line 446 of file extras.c.

00447 {
00448     _papi_hwi_lock( INTERNAL_LOCK );
00449     if ( --_papi_hwi_using_signal[signal] == 0 ) {
00450         INTDBG( "removing signal handler\n" );
00451         if ( sigaction( signal, NULL, NULL ) == -1 ) {
00452             PAPIERROR( "sigaction errno %d", errno );
00453             _papi_hwi_unlock( INTERNAL_LOCK );
00454             return ( PAPI_ESYS );
00455         }
00456     }
00457 
00458     INTDBG( "_papi_hwi_using_signal[%d] is now %d\n", signal,
00459             _papi_hwi_using_signal[signal] );
00460     _papi_hwi_unlock( INTERNAL_LOCK );
00461 
00462     return ( PAPI_OK );
00463 }

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_hwi_stop_timer ( int  timer,
int  signal 
)

Definition at line 466 of file extras.c.

00467 {
00468     struct itimerval value;
00469 
00470 #ifdef ANY_THREAD_GETS_SIGNAL
00471     _papi_hwi_lock( INTERNAL_LOCK );
00472     if ( _papi_hwi_using_signal[signal] > 1 ) {
00473         INTDBG( "itimer in use by another thread\n" );
00474         _papi_hwi_unlock( INTERNAL_LOCK );
00475         return ( PAPI_OK );
00476     }
00477     _papi_hwi_unlock( INTERNAL_LOCK );
00478 #else
00479     ( void ) signal;         /*unused */
00480 #endif
00481 
00482     value.it_interval.tv_sec = 0;
00483     value.it_interval.tv_usec = 0;
00484     value.it_value.tv_sec = 0;
00485     value.it_value.tv_usec = 0;
00486 
00487     INTDBG( "turning off timer\n" );
00488     if ( setitimer( timer, &value, NULL ) == -1 ) {
00489         PAPIERROR( "setitimer errno %d", errno );
00490         return PAPI_ESYS;
00491     }
00492 
00493     return PAPI_OK;
00494 }

Here is the call graph for this function:

Here is the caller graph for this function:


Generated on 26 Jan 2016 for PAPI by  doxygen 1.6.1