|
PAPI
5.0.1.0
|

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) |
| int _papi_hwi_dispatch_overflow_signal | ( | void * | papiContext, |
| caddr_t | address, | ||
| int * | , | ||
| long | long, | ||
| int | , | ||
| ThreadInfo_t ** | master, | ||
| 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 | address, | ||
| 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_initialize | ( | DynamicArray_t ** | ) |
| 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 | ms | ||
| ) |
< 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 );
}

