|
PAPI
5.0.1.0
|

Go to the source code of this file.
Functions | |
| static unsigned short | random_ushort (void) |
| static int | profil_increment (long long value, int flags, long long excess, long long threshold) |
| static void | posix_profil (caddr_t address, PAPI_sprofil_t *prof, int flags, long long excess, long long threshold) |
| void | _papi_hwi_dispatch_profile (EventSetInfo_t *ESI, caddr_t pc, long long over, int profile_index) |
| int | _papi_hwi_dispatch_overflow_signal (void *papiContext, caddr_t address, int *isHardware, long long overflow_bit, int genOverflowBit, ThreadInfo_t **t, int cidx) |
| int | _papi_hwi_start_timer (int timer, int signal, int ns) |
| int | _papi_hwi_start_signal (int signal, int need_context, int cidx) |
| int | _papi_hwi_stop_signal (int signal) |
| int | _papi_hwi_stop_timer (int timer, int signal) |
Variables | |
| static unsigned int | _rnum = 0xdedbeef |
| int | _papi_hwi_using_signal [128] |
| int _papi_hwi_dispatch_overflow_signal | ( | void * | papiContext, |
| caddr_t | address, | ||
| int * | isHardware, | ||
| long long | overflow_bit, | ||
| int | genOverflowBit, | ||
| ThreadInfo_t ** | t, | ||
| int | cidx | ||
| ) |
< EventSet has overflowing enabled
< No error
< Component Index isn't set
< Internal error, please send mail to the developers
< Using Hardware
< EventSet temp. disabled by the library
< Using Hardware
< No error
< Using Hardware
< EventSet has profiling enabled
< Internal error, please send mail to the developers
< Using Hardware
< EventSet temp. disabled by the library
< No error
Definition at line 214 of file extras.c.
{
int retval, event_counter, i, overflow_flag, pos;
int papi_index, j;
int profile_index = 0;
long long overflow_vector;
long long temp[_papi_hwd[cidx]->cmp_info.num_cntrs], over;
long long latest = 0;
ThreadInfo_t *thread;
EventSetInfo_t *ESI;
_papi_hwi_context_t *ctx = ( _papi_hwi_context_t * ) papiContext;
OVFDBG( "enter\n" );
if ( *t )
thread = *t;
else
*t = thread = _papi_hwi_lookup_thread( 0 );
if ( thread != NULL ) {
ESI = thread->running_eventset[cidx];
if ( ( ESI == NULL ) || ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
OVFDBG( "Either no eventset or eventset not set to overflow.\n" );
#ifdef ANY_THREAD_GETS_SIGNAL
_papi_hwi_broadcast_signal( thread->tid );
#endif
return ( PAPI_OK );
}
if ( ESI->CmpIdx != cidx )
return ( PAPI_ENOCMP );
if ( ESI->master != thread ) {
PAPIERROR
( "eventset->thread 0x%lx vs. current thread 0x%lx mismatch",
ESI->master, thread );
return ( PAPI_EBUG );
}
if ( isHardware ) {
if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
ESI->state |= PAPI_PAUSED;
*isHardware = 1;
} else
*isHardware = 0;
}
/* Get the latest counter value */
event_counter = ESI->overflow.event_counter;
overflow_flag = 0;
overflow_vector = 0;
if ( !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
retval = _papi_hwi_read( thread->context[cidx], ESI, ESI->sw_stop );
if ( retval < PAPI_OK )
return ( retval );
for ( i = 0; i < event_counter; i++ ) {
papi_index = ESI->overflow.EventIndex[i];
latest = ESI->sw_stop[papi_index];
temp[i] = -1;
if ( latest >= ( long long ) ESI->overflow.deadline[i] ) {
OVFDBG
( "dispatch_overflow() latest %lld, deadline %lld, threshold %d\n",
latest, ESI->overflow.deadline[i],
ESI->overflow.threshold[i] );
pos = ESI->EventInfoArray[papi_index].pos[0];
overflow_vector ^= ( long long ) 1 << pos;
temp[i] = latest - ESI->overflow.deadline[i];
overflow_flag = 1;
/* adjust the deadline */
ESI->overflow.deadline[i] =
latest + ESI->overflow.threshold[i];
}
}
} else if ( genOverflowBit ) {
/* we had assumed the overflow event can't be derived event */
papi_index = ESI->overflow.EventIndex[0];
/* suppose the pos is the same as the counter number
* (this is not true in Itanium, but itanium doesn't
* need us to generate the overflow bit
*/
pos = ESI->EventInfoArray[papi_index].pos[0];
overflow_vector = ( long long ) 1 << pos;
} else
overflow_vector = overflow_bit;
if ( ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) || overflow_flag ) {
if ( ESI->state & PAPI_PROFILING ) {
int k = 0;
while ( overflow_vector ) {
i = ffsll( overflow_vector ) - 1;
for ( j = 0; j < event_counter; j++ ) {
papi_index = ESI->overflow.EventIndex[j];
/* This loop is here ONLY because Pentium 4 can have tagged *
* events that contain more than one counter without being *
* derived. You've gotta scan all terms to make sure you *
* find the one to profile. */
for ( k = 0, pos = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT && pos >= 0;
k++ ) {
pos = ESI->EventInfoArray[papi_index].pos[k];
if ( i == pos ) {
profile_index = j;
goto foundit;
}
}
}
if ( j == event_counter ) {
PAPIERROR
( "BUG! overflow_vector is 0, dropping interrupt" );
return ( PAPI_EBUG );
}
foundit:
if ( ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) )
over = 0;
else
over = temp[profile_index];
_papi_hwi_dispatch_profile( ESI, address, over,
profile_index );
overflow_vector ^= ( long long ) 1 << i;
}
/* do not use overflow_vector after this place */
} else {
ESI->overflow.handler( ESI->EventSetIndex, ( void * ) address,
overflow_vector, ctx->ucontext );
}
}
ESI->state &= ~( PAPI_PAUSED );
}
#ifdef ANY_THREAD_GETS_SIGNAL
else {
OVFDBG( "I haven't been noticed by PAPI before\n" );
_papi_hwi_broadcast_signal( ( *_papi_hwi_thread_id_fn ) ( ) );
}
#endif
return ( PAPI_OK );
}


| void _papi_hwi_dispatch_profile | ( | EventSetInfo_t * | ESI, |
| caddr_t | pc, | ||
| long long | over, | ||
| int | profile_index | ||
| ) |
Definition at line 163 of file extras.c.
{
EventSetProfileInfo_t *profile = &ESI->profile;
PAPI_sprofil_t *sprof;
caddr_t offset = 0;
caddr_t best_offset = 0;
int count;
int best_index = -1;
int i;
PRFDBG( "handled IP 0x%p\n", pc );
sprof = profile->prof[profile_index];
count = profile->count[profile_index];
for ( i = 0; i < count; i++ ) {
offset = sprof[i].pr_off;
if ( ( offset < pc ) && ( offset > best_offset ) ) {
best_index = i;
best_offset = offset;
}
}
if ( best_index == -1 )
best_index = 0;
posix_profil( pc, &sprof[best_index], profile->flags, over,
profile->threshold[profile_index] );
}


| int _papi_hwi_start_signal | ( | int | signal, |
| int | need_context, | ||
| int | cidx | ||
| ) |
< Used with setting up array
< Used with setting up array
< No error
< Used with setting up array
< A System/C library call failed
< Used with setting up array
< No error
Definition at line 401 of file extras.c.
{
struct sigaction action;
_papi_hwi_lock( INTERNAL_LOCK );
_papi_hwi_using_signal[signal]++;
if ( _papi_hwi_using_signal[signal] - 1 ) {
INTDBG( "_papi_hwi_using_signal is now %d\n",
_papi_hwi_using_signal[signal] );
_papi_hwi_unlock( INTERNAL_LOCK );
return ( PAPI_OK );
}
memset( &action, 0x00, sizeof ( struct sigaction ) );
action.sa_flags = SA_RESTART;
action.sa_sigaction =
( void ( * )( int, siginfo_t *, void * ) ) _papi_hwd[cidx]->
dispatch_timer;
if ( need_context )
#if (defined(_BGL) /*|| defined (__bgp__)*/)
action.sa_flags |= SIGPWR;
#else
action.sa_flags |= SA_SIGINFO;
#endif
INTDBG( "installing signal handler\n" );
if ( sigaction( signal, &action, NULL ) < 0 ) {
PAPIERROR( "sigaction errno %d", errno );
_papi_hwi_unlock( INTERNAL_LOCK );
return ( PAPI_ESYS );
}
INTDBG( "_papi_hwi_using_signal[%d] is now %d.\n", signal,
_papi_hwi_using_signal[signal] );
_papi_hwi_unlock( INTERNAL_LOCK );
return ( PAPI_OK );
}


| int _papi_hwi_start_timer | ( | int | timer, |
| int | signal, | ||
| int | ns | ||
| ) |
< A System/C library call failed
< No error
Definition at line 366 of file extras.c.
{
struct itimerval value;
int us = ns / 1000;
if ( us == 0 )
us = 1;
#ifdef ANY_THREAD_GETS_SIGNAL
_papi_hwi_lock( INTERNAL_LOCK );
if ( ( _papi_hwi_using_signal[signal] - 1 ) ) {
INTDBG( "itimer already installed\n" );
_papi_hwi_unlock( INTERNAL_LOCK );
return ( PAPI_OK );
}
_papi_hwi_unlock( INTERNAL_LOCK );
#else
( void ) signal; /*unused */
#endif
value.it_interval.tv_sec = 0;
value.it_interval.tv_usec = us;
value.it_value.tv_sec = 0;
value.it_value.tv_usec = us;
INTDBG( "Installing itimer %d, with %d us interval\n", timer, us );
if ( setitimer( timer, &value, NULL ) < 0 ) {
PAPIERROR( "setitimer errno %d", errno );
return ( PAPI_ESYS );
}
return ( PAPI_OK );
}


| int _papi_hwi_stop_signal | ( | int | signal | ) |
< Used with setting up array
< Used with setting up array
< A System/C library call failed
< Used with setting up array
< No error
Definition at line 441 of file extras.c.
{
_papi_hwi_lock( INTERNAL_LOCK );
if ( --_papi_hwi_using_signal[signal] == 0 ) {
INTDBG( "removing signal handler\n" );
if ( sigaction( signal, NULL, NULL ) == -1 ) {
PAPIERROR( "sigaction errno %d", errno );
_papi_hwi_unlock( INTERNAL_LOCK );
return ( PAPI_ESYS );
}
}
INTDBG( "_papi_hwi_using_signal[%d] is now %d\n", signal,
_papi_hwi_using_signal[signal] );
_papi_hwi_unlock( INTERNAL_LOCK );
return ( PAPI_OK );
}


| int _papi_hwi_stop_timer | ( | int | timer, |
| int | signal | ||
| ) |
< A System/C library call failed
< No error
Definition at line 461 of file extras.c.
{
#ifdef ANY_THREAD_GETS_SIGNAL
_papi_hwi_lock( INTERNAL_LOCK );
if ( _papi_hwi_using_signal[signal] > 1 ) {
INTDBG( "itimer in use by another thread\n" );
_papi_hwi_unlock( INTERNAL_LOCK );
return ( PAPI_OK );
}
_papi_hwi_unlock( INTERNAL_LOCK );
#else
( void ) signal; /*unused */
#endif
INTDBG( "turning off timer\n" );
if ( setitimer( timer, NULL, NULL ) == -1 ) {
PAPIERROR( "setitimer errno %d", errno );
return ( PAPI_ESYS );
}
return ( PAPI_OK );
}


| static void posix_profil | ( | caddr_t | address, |
| PAPI_sprofil_t * | prof, | ||
| int | flags, | ||
| long long | excess, | ||
| long long | threshold | ||
| ) | [static] |
< Use 16 bit buckets to accumulate profile info (default)
< Use 32 bit buckets to accumulate profile info
Definition at line 92 of file extras.c.
{
unsigned short *buf16;
unsigned int *buf32;
unsigned long long *buf64;
unsigned long indx;
unsigned long long lloffset;
/* SPECIAL CASE: if starting address is 0 and scale factor is 2
then all counts go into first bin.
*/
if ( ( prof->pr_off == 0 ) && ( prof->pr_scale == 0x2 ) )
indx = 0;
else {
/* compute the profile buffer offset by:
- subtracting the profiling base address from the pc address
- multiplying by the scaling factor
- dividing by max scale (65536, or 2^^16)
- dividing by implicit 2 (2^^1 for a total of 2^^17), for even addresses
NOTE: 131072 is a valid scale value. It produces byte resolution of addresses
*/
lloffset =
( unsigned long long ) ( ( address - prof->pr_off ) *
prof->pr_scale );
indx = ( unsigned long ) ( lloffset >> 17 );
}
/* confirm addresses within specified range */
if ( address >= prof->pr_off ) {
/* test first for 16-bit buckets; this should be the fast case */
if ( flags & PAPI_PROFIL_BUCKET_16 ) {
if ( ( indx * sizeof ( short ) ) < prof->pr_size ) {
buf16 = prof->pr_base;
buf16[indx] =
( unsigned short ) ( ( unsigned short ) buf16[indx] +
profil_increment( buf16[indx], flags,
excess,
threshold ) );
PRFDBG( "posix_profil_16() bucket %lu = %u\n", indx,
buf16[indx] );
}
}
/* next, look for the 32-bit case */
else if ( flags & PAPI_PROFIL_BUCKET_32 ) {
if ( ( indx * sizeof ( int ) ) < prof->pr_size ) {
buf32 = prof->pr_base;
buf32[indx] = ( unsigned int ) buf32[indx] +
( unsigned int ) profil_increment( buf32[indx], flags,
excess, threshold );
PRFDBG( "posix_profil_32() bucket %lu = %u\n", indx,
buf32[indx] );
}
}
/* finally, fall through to the 64-bit case */
else {
if ( ( indx * sizeof ( long long ) ) < prof->pr_size ) {
buf64 = prof->pr_base;
buf64[indx] = ( unsigned long long ) buf64[indx] +
( unsigned long long ) profil_increment( ( long long )
buf64[indx], flags,
excess,
threshold );
PRFDBG( "posix_profil_64() bucket %lu = %lld\n", indx,
buf64[indx] );
}
}
}
}


| static int profil_increment | ( | long long | value, |
| int | flags, | ||
| long long | excess, | ||
| long long | threshold | ||
| ) | [inline, static] |
< Default type of profiling, similar to 'man profil'.
< Drop a random 25% of the samples.
< Ignore samples if hash buckets get big.
< Weight the samples by their value.
Definition at line 56 of file extras.c.
{
int increment = 1;
if ( flags == PAPI_PROFIL_POSIX ) {
return ( 1 );
}
if ( flags & PAPI_PROFIL_RANDOM ) {
if ( random_ushort( ) <= ( USHRT_MAX / 4 ) )
return ( 0 );
}
if ( flags & PAPI_PROFIL_COMPRESS ) {
/* We're likely to ignore the sample if buf[address] gets big. */
if ( random_ushort( ) < value ) {
return ( 0 );
}
}
if ( flags & PAPI_PROFIL_WEIGHTED ) { /* Increment is between 1 and 255 */
if ( excess <= ( long long ) 1 )
increment = 1;
else if ( excess > threshold )
increment = 255;
else {
threshold = threshold / ( long long ) 255;
increment = ( int ) ( excess / threshold );
}
}
return ( increment );
}


| static unsigned short random_ushort | ( | void | ) | [inline, static] |
| int _papi_hwi_using_signal[128] |