Blame src/extras.c

Packit Service a1973e
/****************************/
Packit Service a1973e
/* THIS IS OPEN SOURCE CODE */
Packit Service a1973e
/****************************/
Packit Service a1973e
Packit Service a1973e
/* 
Packit Service a1973e
* File:    extras.c
Packit Service a1973e
* Author:  Philip Mucci
Packit Service a1973e
*          mucci@cs.utk.edu
Packit Service a1973e
* Mods:    dan terpstra
Packit Service a1973e
*          terpstra@cs.utk.edu
Packit Service a1973e
* Mods:    Haihang You
Packit Service a1973e
*          you@cs.utk.edu
Packit Service a1973e
* Mods:    Kevin London
Packit Service a1973e
*          london@cs.utk.edu
Packit Service a1973e
* Mods:    Maynard Johnson
Packit Service a1973e
*          maynardj@us.ibm.com
Packit Service a1973e
*/
Packit Service a1973e
Packit Service a1973e
/* This file contains portable routines to do things that we wish the
Packit Service a1973e
vendors did in the kernel extensions or performance libraries. */
Packit Service a1973e
Packit Service a1973e
#include "papi.h"
Packit Service a1973e
#include "papi_internal.h"
Packit Service a1973e
#include "papi_vector.h"
Packit Service a1973e
#include "papi_memory.h"
Packit Service a1973e
#include "extras.h"
Packit Service a1973e
#include "threads.h"
Packit Service a1973e
Packit Service a1973e
#if (!defined(HAVE_FFSLL) || defined(__bgp__))
Packit Service a1973e
int ffsll( long long lli );
Packit Service a1973e
#else
Packit Service a1973e
#include <string.h>
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
/****************/
Packit Service a1973e
/* BEGIN LOCALS */
Packit Service a1973e
/****************/
Packit Service a1973e
Packit Service a1973e
static unsigned int _rnum = DEADBEEF;
Packit Service a1973e
Packit Service a1973e
/**************/
Packit Service a1973e
/* END LOCALS */
Packit Service a1973e
/**************/
Packit Service a1973e
Packit Service a1973e
inline_static unsigned short
Packit Service a1973e
random_ushort( void )
Packit Service a1973e
{
Packit Service a1973e
	return ( unsigned short ) ( _rnum = 1664525 * _rnum + 1013904223 );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
/* compute the amount by which to increment the bucket.
Packit Service a1973e
   value is the current value of the bucket
Packit Service a1973e
   this routine is used by all three profiling cases
Packit Service a1973e
   it is inlined for speed
Packit Service a1973e
*/
Packit Service a1973e
inline_static int
Packit Service a1973e
profil_increment( long long value,
Packit Service a1973e
				  int flags, long long excess, long long threshold )
Packit Service a1973e
{
Packit Service a1973e
	int increment = 1;
Packit Service a1973e
Packit Service a1973e
	if ( flags == PAPI_PROFIL_POSIX ) {
Packit Service a1973e
		return ( 1 );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( flags & PAPI_PROFIL_RANDOM ) {
Packit Service a1973e
		if ( random_ushort(  ) <= ( USHRT_MAX / 4 ) )
Packit Service a1973e
			return ( 0 );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( flags & PAPI_PROFIL_COMPRESS ) {
Packit Service a1973e
		/* We're likely to ignore the sample if buf[address] gets big. */
Packit Service a1973e
		if ( random_ushort(  ) < value ) {
Packit Service a1973e
			return ( 0 );
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( flags & PAPI_PROFIL_WEIGHTED ) {	/* Increment is between 1 and 255 */
Packit Service a1973e
		if ( excess <= ( long long ) 1 )
Packit Service a1973e
			increment = 1;
Packit Service a1973e
		else if ( excess > threshold )
Packit Service a1973e
			increment = 255;
Packit Service a1973e
		else {
Packit Service a1973e
			threshold = threshold / ( long long ) 255;
Packit Service a1973e
			increment = ( int ) ( excess / threshold );
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
	return ( increment );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
static void
Packit Service a1973e
posix_profil( caddr_t address, PAPI_sprofil_t * prof,
Packit Service a1973e
			  int flags, long long excess, long long threshold )
Packit Service a1973e
{
Packit Service a1973e
	unsigned short *buf16;
Packit Service a1973e
	unsigned int *buf32;
Packit Service a1973e
	unsigned long long *buf64;
Packit Service a1973e
	unsigned long indx;
Packit Service a1973e
	unsigned long long lloffset;
Packit Service a1973e
Packit Service a1973e
	/* SPECIAL CASE: if starting address is 0 and scale factor is 2
Packit Service a1973e
	   then all counts go into first bin.
Packit Service a1973e
	 */
Packit Service a1973e
	if ( ( prof->pr_off == 0 ) && ( prof->pr_scale == 0x2 ) )
Packit Service a1973e
		indx = 0;
Packit Service a1973e
	else {
Packit Service a1973e
		/* compute the profile buffer offset by:
Packit Service a1973e
		   - subtracting the profiling base address from the pc address
Packit Service a1973e
		   - multiplying by the scaling factor
Packit Service a1973e
		   - dividing by max scale (65536, or 2^^16) 
Packit Service a1973e
		   - dividing by implicit 2 (2^^1 for a total of 2^^17), for even addresses
Packit Service a1973e
		   NOTE: 131072 is a valid scale value. It produces byte resolution of addresses
Packit Service a1973e
		 */
Packit Service a1973e
		lloffset =
Packit Service a1973e
			( unsigned long long ) ( ( address - prof->pr_off ) *
Packit Service a1973e
									 prof->pr_scale );
Packit Service a1973e
		indx = ( unsigned long ) ( lloffset >> 17 );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	/* confirm addresses within specified range */
Packit Service a1973e
	if ( address >= prof->pr_off ) {
Packit Service a1973e
		/* test first for 16-bit buckets; this should be the fast case */
Packit Service a1973e
		if ( flags & PAPI_PROFIL_BUCKET_16 ) {
Packit Service a1973e
			if ( ( indx * sizeof ( short ) ) < prof->pr_size ) {
Packit Service a1973e
				buf16 = (unsigned short *) prof->pr_base;
Packit Service a1973e
				buf16[indx] =
Packit Service a1973e
					( unsigned short ) ( ( unsigned short ) buf16[indx] +
Packit Service a1973e
										 profil_increment( buf16[indx], flags,
Packit Service a1973e
														   excess,
Packit Service a1973e
														   threshold ) );
Packit Service a1973e
				PRFDBG( "posix_profil_16() bucket %lu = %u\n", indx,
Packit Service a1973e
						buf16[indx] );
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
		/* next, look for the 32-bit case */
Packit Service a1973e
		else if ( flags & PAPI_PROFIL_BUCKET_32 ) {
Packit Service a1973e
			if ( ( indx * sizeof ( int ) ) < prof->pr_size ) {
Packit Service a1973e
				buf32 = (unsigned int *) prof->pr_base;
Packit Service a1973e
				buf32[indx] = ( unsigned int ) buf32[indx] +
Packit Service a1973e
					( unsigned int ) profil_increment( buf32[indx], flags,
Packit Service a1973e
													   excess, threshold );
Packit Service a1973e
				PRFDBG( "posix_profil_32() bucket %lu = %u\n", indx,
Packit Service a1973e
						buf32[indx] );
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
		/* finally, fall through to the 64-bit case */
Packit Service a1973e
		else {
Packit Service a1973e
			if ( ( indx * sizeof ( long long ) ) < prof->pr_size ) {
Packit Service a1973e
				buf64 = (unsigned long long *) prof->pr_base;
Packit Service a1973e
				buf64[indx] = ( unsigned long long ) buf64[indx] +
Packit Service a1973e
					( unsigned long long ) profil_increment( ( long long )
Packit Service a1973e
															 buf64[indx], flags,
Packit Service a1973e
															 excess,
Packit Service a1973e
															 threshold );
Packit Service a1973e
				PRFDBG( "posix_profil_64() bucket %lu = %lld\n", indx,
Packit Service a1973e
						buf64[indx] );
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
void
Packit Service a1973e
_papi_hwi_dispatch_profile( EventSetInfo_t * ESI, caddr_t pc,
Packit Service a1973e
							long long over, int profile_index )
Packit Service a1973e
{
Packit Service a1973e
	EventSetProfileInfo_t *profile = &ESI->profile;
Packit Service a1973e
	PAPI_sprofil_t *sprof;
Packit Service a1973e
	caddr_t offset = 0;
Packit Service a1973e
	caddr_t best_offset = 0;
Packit Service a1973e
	int count;
Packit Service a1973e
	int best_index = -1;
Packit Service a1973e
	int i;
Packit Service a1973e
Packit Service a1973e
	PRFDBG( "handled IP %p\n", pc );
Packit Service a1973e
Packit Service a1973e
	sprof = profile->prof[profile_index];
Packit Service a1973e
	count = profile->count[profile_index];
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < count; i++ ) {
Packit Service a1973e
		offset = sprof[i].pr_off;
Packit Service a1973e
		if ( ( offset < pc ) && ( offset > best_offset ) ) {
Packit Service a1973e
			best_index = i;
Packit Service a1973e
			best_offset = offset;
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	if ( best_index == -1 )
Packit Service a1973e
		best_index = 0;
Packit Service a1973e
Packit Service a1973e
	posix_profil( pc, &sprof[best_index], profile->flags, over,
Packit Service a1973e
				  profile->threshold[profile_index] );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
/* if isHardware is true, then the processor is using hardware overflow,
Packit Service a1973e
   else it is using software overflow. Use this parameter instead of 
Packit Service a1973e
   _papi_hwi_system_info.supports_hw_overflow is in CRAY some processors
Packit Service a1973e
   may use hardware overflow, some may use software overflow.
Packit Service a1973e
Packit Service a1973e
   overflow_bit: if the component can get the overflow bit when overflow
Packit Service a1973e
                 occurs, then this should be passed by the component;
Packit Service a1973e
Packit Service a1973e
   If both genOverflowBit and isHardwareSupport are true, that means
Packit Service a1973e
     the component doesn't know how to get the overflow bit from the
Packit Service a1973e
     kernel directly, so we generate the overflow bit in this function 
Packit Service a1973e
    since this function can access the ESI->overflow struct;
Packit Service a1973e
   (The component can only set genOverflowBit parameter to true if the
Packit Service a1973e
     hardware doesn't support multiple hardware overflow. If the
Packit Service a1973e
     component supports multiple hardware overflow and you don't know how 
Packit Service a1973e
     to get the overflow bit, then I don't know how to deal with this 
Packit Service a1973e
     situation).
Packit Service a1973e
*/
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_papi_hwi_dispatch_overflow_signal( void *papiContext, caddr_t address,
Packit Service a1973e
				   int *isHardware, long long overflow_bit,
Packit Service a1973e
				   int genOverflowBit, ThreadInfo_t ** t,
Packit Service a1973e
				   int cidx )
Packit Service a1973e
{
Packit Service a1973e
	int retval, event_counter, i, overflow_flag, pos;
Packit Service a1973e
	int papi_index, j;
Packit Service a1973e
	int profile_index = 0;
Packit Service a1973e
	long long overflow_vector;
Packit Service a1973e
Packit Service a1973e
	long long temp[_papi_hwd[cidx]->cmp_info.num_cntrs], over;
Packit Service a1973e
	long long latest = 0;
Packit Service a1973e
	ThreadInfo_t *thread;
Packit Service a1973e
	EventSetInfo_t *ESI;
Packit Service a1973e
	_papi_hwi_context_t *ctx = ( _papi_hwi_context_t * ) papiContext;
Packit Service a1973e
Packit Service a1973e
	OVFDBG( "enter\n" );
Packit Service a1973e
Packit Service a1973e
	if ( *t )
Packit Service a1973e
		thread = *t;
Packit Service a1973e
	else
Packit Service a1973e
		*t = thread = _papi_hwi_lookup_thread( 0 );
Packit Service a1973e
Packit Service a1973e
	if ( thread != NULL ) {
Packit Service a1973e
		ESI = thread->running_eventset[cidx];
Packit Service a1973e
Packit Service a1973e
		if ( ( ESI == NULL ) || ( ( ESI->state & PAPI_OVERFLOWING ) == 0 ) ) {
Packit Service a1973e
			OVFDBG( "Either no eventset or eventset not set to overflow.\n" );
Packit Service a1973e
#ifdef ANY_THREAD_GETS_SIGNAL
Packit Service a1973e
			_papi_hwi_broadcast_signal( thread->tid );
Packit Service a1973e
#endif
Packit Service a1973e
			return ( PAPI_OK );
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		if ( ESI->CmpIdx != cidx )
Packit Service a1973e
			return ( PAPI_ENOCMP );
Packit Service a1973e
Packit Service a1973e
		if ( ESI->master != thread ) {
Packit Service a1973e
			PAPIERROR
Packit Service a1973e
				( "eventset->thread %#lx vs. current thread %#lx mismatch",
Packit Service a1973e
				  ESI->master, thread );
Packit Service a1973e
			return ( PAPI_EBUG );
Packit Service a1973e
		}
Packit Service a1973e
Packit Service a1973e
		if ( isHardware ) {
Packit Service a1973e
			if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
Packit Service a1973e
				ESI->state |= PAPI_PAUSED;
Packit Service a1973e
				*isHardware = 1;
Packit Service a1973e
			} else
Packit Service a1973e
				*isHardware = 0;
Packit Service a1973e
		}
Packit Service a1973e
		/* Get the latest counter value */
Packit Service a1973e
		event_counter = ESI->overflow.event_counter;
Packit Service a1973e
Packit Service a1973e
		overflow_flag = 0;
Packit Service a1973e
		overflow_vector = 0;
Packit Service a1973e
Packit Service a1973e
		if ( !( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) ) {
Packit Service a1973e
			retval = _papi_hwi_read( thread->context[cidx], ESI, ESI->sw_stop );
Packit Service a1973e
			if ( retval < PAPI_OK )
Packit Service a1973e
				return ( retval );
Packit Service a1973e
			for ( i = 0; i < event_counter; i++ ) {
Packit Service a1973e
				papi_index = ESI->overflow.EventIndex[i];
Packit Service a1973e
				latest = ESI->sw_stop[papi_index];
Packit Service a1973e
				temp[i] = -1;
Packit Service a1973e
Packit Service a1973e
				if ( latest >= ( long long ) ESI->overflow.deadline[i] ) {
Packit Service a1973e
					OVFDBG
Packit Service a1973e
						( "dispatch_overflow() latest %lld, deadline %lld, threshold %d\n",
Packit Service a1973e
						  latest, ESI->overflow.deadline[i],
Packit Service a1973e
						  ESI->overflow.threshold[i] );
Packit Service a1973e
					pos = ESI->EventInfoArray[papi_index].pos[0];
Packit Service a1973e
					overflow_vector ^= ( long long ) 1 << pos;
Packit Service a1973e
					temp[i] = latest - ESI->overflow.deadline[i];
Packit Service a1973e
					overflow_flag = 1;
Packit Service a1973e
					/* adjust the deadline */
Packit Service a1973e
					ESI->overflow.deadline[i] =
Packit Service a1973e
						latest + ESI->overflow.threshold[i];
Packit Service a1973e
				}
Packit Service a1973e
			}
Packit Service a1973e
		} else if ( genOverflowBit ) {
Packit Service a1973e
			/* we had assumed the overflow event can't be derived event */
Packit Service a1973e
			papi_index = ESI->overflow.EventIndex[0];
Packit Service a1973e
Packit Service a1973e
			/* suppose the pos is the same as the counter number
Packit Service a1973e
			 * (this is not true in Itanium, but itanium doesn't 
Packit Service a1973e
			 * need us to generate the overflow bit
Packit Service a1973e
			 */
Packit Service a1973e
			pos = ESI->EventInfoArray[papi_index].pos[0];
Packit Service a1973e
			overflow_vector = ( long long ) 1 << pos;
Packit Service a1973e
		} else
Packit Service a1973e
			overflow_vector = overflow_bit;
Packit Service a1973e
Packit Service a1973e
		if ( ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) || overflow_flag ) {
Packit Service a1973e
			if ( ESI->state & PAPI_PROFILING ) {
Packit Service a1973e
				int k = 0;
Packit Service a1973e
				while ( overflow_vector ) {
Packit Service a1973e
					i = ffsll( overflow_vector ) - 1;
Packit Service a1973e
					for ( j = 0; j < event_counter; j++ ) {
Packit Service a1973e
						papi_index = ESI->overflow.EventIndex[j];
Packit Service a1973e
						/* This loop is here ONLY because Pentium 4 can have tagged *
Packit Service a1973e
						 * events that contain more than one counter without being  *
Packit Service a1973e
						 * derived. You've gotta scan all terms to make sure you    *
Packit Service a1973e
						 * find the one to profile. */
Packit Service a1973e
						for ( k = 0, pos = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT && pos >= 0;
Packit Service a1973e
							  k++ ) {
Packit Service a1973e
							pos = ESI->EventInfoArray[papi_index].pos[k];
Packit Service a1973e
							if ( i == pos ) {
Packit Service a1973e
								profile_index = j;
Packit Service a1973e
								goto foundit;
Packit Service a1973e
							}
Packit Service a1973e
						}
Packit Service a1973e
					}
Packit Service a1973e
					if ( j == event_counter ) {
Packit Service a1973e
						PAPIERROR
Packit Service a1973e
							( "BUG! overflow_vector is 0, dropping interrupt" );
Packit Service a1973e
						return ( PAPI_EBUG );
Packit Service a1973e
					}
Packit Service a1973e
Packit Service a1973e
				  foundit:
Packit Service a1973e
					if ( ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) )
Packit Service a1973e
						over = 0;
Packit Service a1973e
					else
Packit Service a1973e
						over = temp[profile_index];
Packit Service a1973e
					_papi_hwi_dispatch_profile( ESI, address, over,
Packit Service a1973e
												profile_index );
Packit Service a1973e
					overflow_vector ^= ( long long ) 1 << i;
Packit Service a1973e
				}
Packit Service a1973e
				/* do not use overflow_vector after this place */
Packit Service a1973e
			} else {
Packit Service a1973e
				ESI->overflow.handler( ESI->EventSetIndex, ( void * ) address,
Packit Service a1973e
									   overflow_vector, ctx->ucontext );
Packit Service a1973e
			}
Packit Service a1973e
		}
Packit Service a1973e
		ESI->state &= ~( PAPI_PAUSED );
Packit Service a1973e
	}
Packit Service a1973e
#ifdef ANY_THREAD_GETS_SIGNAL
Packit Service a1973e
	else {
Packit Service a1973e
		OVFDBG( "I haven't been noticed by PAPI before\n" );
Packit Service a1973e
		_papi_hwi_broadcast_signal( ( *_papi_hwi_thread_id_fn ) (  ) );
Packit Service a1973e
	}
Packit Service a1973e
#endif
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
#include <sys/time.h>
Packit Service a1973e
#include <errno.h>
Packit Service a1973e
#include <string.h>
Packit Service a1973e
Packit Service a1973e
int _papi_hwi_using_signal[PAPI_NSIG];
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_papi_hwi_start_timer( int timer, int signal, int ns )
Packit Service a1973e
{
Packit Service a1973e
	struct itimerval value;
Packit Service a1973e
	int us = ns / 1000;
Packit Service a1973e
Packit Service a1973e
	if ( us == 0 )
Packit Service a1973e
		us = 1;
Packit Service a1973e
Packit Service a1973e
#ifdef ANY_THREAD_GETS_SIGNAL
Packit Service a1973e
	_papi_hwi_lock( INTERNAL_LOCK );
Packit Service a1973e
	if ( ( _papi_hwi_using_signal[signal] - 1 ) ) {
Packit Service a1973e
		INTDBG( "itimer already installed\n" );
Packit Service a1973e
		_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
		return ( PAPI_OK );
Packit Service a1973e
	}
Packit Service a1973e
	_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
#else
Packit Service a1973e
	( void ) signal;		 /*unused */
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	value.it_interval.tv_sec = 0;
Packit Service a1973e
	value.it_interval.tv_usec = us;
Packit Service a1973e
	value.it_value.tv_sec = 0;
Packit Service a1973e
	value.it_value.tv_usec = us;
Packit Service a1973e
Packit Service a1973e
	INTDBG( "Installing itimer %d, with %d us interval\n", timer, us );
Packit Service a1973e
	if ( setitimer( timer, &value, NULL ) < 0 ) {
Packit Service a1973e
		PAPIERROR( "setitimer errno %d", errno );
Packit Service a1973e
		return ( PAPI_ESYS );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_papi_hwi_start_signal( int signal, int need_context, int cidx )
Packit Service a1973e
{
Packit Service a1973e
	struct sigaction action;
Packit Service a1973e
Packit Service a1973e
	_papi_hwi_lock( INTERNAL_LOCK );
Packit Service a1973e
	_papi_hwi_using_signal[signal]++;
Packit Service a1973e
	if ( _papi_hwi_using_signal[signal] - 1 ) {
Packit Service a1973e
		INTDBG( "_papi_hwi_using_signal is now %d\n",
Packit Service a1973e
				_papi_hwi_using_signal[signal] );
Packit Service a1973e
		_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
		return ( PAPI_OK );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	memset( &action, 0x00, sizeof ( struct sigaction ) );
Packit Service a1973e
	action.sa_flags = SA_RESTART;
Packit Service a1973e
	action.sa_sigaction =
Packit Service a1973e
		( void ( * )( int, siginfo_t *, void * ) ) _papi_hwd[cidx]->
Packit Service a1973e
		dispatch_timer;
Packit Service a1973e
	if ( need_context )
Packit Service a1973e
#if (defined(_BGL) /*|| defined (__bgp__)*/)
Packit Service a1973e
		action.sa_flags |= SIGPWR;
Packit Service a1973e
#else
Packit Service a1973e
		action.sa_flags |= SA_SIGINFO;
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	INTDBG( "installing signal handler\n" );
Packit Service a1973e
	if ( sigaction( signal, &action, NULL ) < 0 ) {
Packit Service a1973e
		PAPIERROR( "sigaction errno %d", errno );
Packit Service a1973e
		_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
		return ( PAPI_ESYS );
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	INTDBG( "_papi_hwi_using_signal[%d] is now %d.\n", signal,
Packit Service a1973e
			_papi_hwi_using_signal[signal] );
Packit Service a1973e
	_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_papi_hwi_stop_signal( int signal )
Packit Service a1973e
{
Packit Service a1973e
	_papi_hwi_lock( INTERNAL_LOCK );
Packit Service a1973e
	if ( --_papi_hwi_using_signal[signal] == 0 ) {
Packit Service a1973e
		INTDBG( "removing signal handler\n" );
Packit Service a1973e
		if ( sigaction( signal, NULL, NULL ) == -1 ) {
Packit Service a1973e
			PAPIERROR( "sigaction errno %d", errno );
Packit Service a1973e
			_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
			return ( PAPI_ESYS );
Packit Service a1973e
		}
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	INTDBG( "_papi_hwi_using_signal[%d] is now %d\n", signal,
Packit Service a1973e
			_papi_hwi_using_signal[signal] );
Packit Service a1973e
	_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
Packit Service a1973e
	return ( PAPI_OK );
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
_papi_hwi_stop_timer( int timer, int signal )
Packit Service a1973e
{
Packit Service a1973e
	struct itimerval value;
Packit Service a1973e
Packit Service a1973e
#ifdef ANY_THREAD_GETS_SIGNAL
Packit Service a1973e
	_papi_hwi_lock( INTERNAL_LOCK );
Packit Service a1973e
	if ( _papi_hwi_using_signal[signal] > 1 ) {
Packit Service a1973e
		INTDBG( "itimer in use by another thread\n" );
Packit Service a1973e
		_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
		return ( PAPI_OK );
Packit Service a1973e
	}
Packit Service a1973e
	_papi_hwi_unlock( INTERNAL_LOCK );
Packit Service a1973e
#else
Packit Service a1973e
	( void ) signal;		 /*unused */
Packit Service a1973e
#endif
Packit Service a1973e
Packit Service a1973e
	value.it_interval.tv_sec = 0;
Packit Service a1973e
	value.it_interval.tv_usec = 0;
Packit Service a1973e
	value.it_value.tv_sec = 0;
Packit Service a1973e
	value.it_value.tv_usec = 0;
Packit Service a1973e
Packit Service a1973e
	INTDBG( "turning off timer\n" );
Packit Service a1973e
	if ( setitimer( timer, &value, NULL ) == -1 ) {
Packit Service a1973e
		PAPIERROR( "setitimer errno %d", errno );
Packit Service a1973e
		return PAPI_ESYS;
Packit Service a1973e
	}
Packit Service a1973e
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
Packit Service a1973e
#if (!defined(HAVE_FFSLL) || defined(__bgp__))
Packit Service a1973e
/* find the first set bit in long long */
Packit Service a1973e
Packit Service a1973e
int
Packit Service a1973e
ffsll( long long lli )
Packit Service a1973e
{
Packit Service a1973e
	int i, num, t, tmpint, len;
Packit Service a1973e
Packit Service a1973e
	num = sizeof ( long long ) / sizeof ( int );
Packit Service a1973e
	if ( num == 1 )
Packit Service a1973e
		return ( ffs( ( int ) lli ) );
Packit Service a1973e
	len = sizeof ( int ) * CHAR_BIT;
Packit Service a1973e
Packit Service a1973e
	for ( i = 0; i < num; i++ ) {
Packit Service a1973e
		tmpint = ( int ) ( ( ( lli >> len ) << len ) ^ lli );
Packit Service a1973e
Packit Service a1973e
		t = ffs( tmpint );
Packit Service a1973e
		if ( t ) {
Packit Service a1973e
			return ( t + i * len );
Packit Service a1973e
		}
Packit Service a1973e
		lli = lli >> len;
Packit Service a1973e
	}
Packit Service a1973e
	return PAPI_OK;
Packit Service a1973e
}
Packit Service a1973e
#endif