|
PAPI
5.0.1.0
|

Go to the source code of this file.
Defines | |
| #define | PFM_MAX_PMCDS 20 |
| #define | BPL (sizeof(uint64_t)<<3) |
| #define | LBPL 6 |
Typedefs | |
| typedef unsigned | uint |
Functions | |
| static int | _papi_pfm_set_overflow (EventSetInfo_t *ESI, int EventIndex, int threshold) |
| int | _papi_pfm_write_pmcs (pfm_context_t *ctx, pfm_control_state_t *ctl) |
| int | _papi_pfm_write_pmds (pfm_context_t *ctx, pfm_control_state_t *ctl) |
| int | _papi_pfm_read_pmds (pfm_context_t *ctx, pfm_control_state_t *ctl) |
| static int | check_multiplex_timeout (int ctx_fd, unsigned long *timeout_ns) |
| static int | detect_timeout_and_unavail_pmu_regs (pfmlib_regmask_t *r_pmcs, pfmlib_regmask_t *r_pmds, unsigned long *timeout_ns) |
| static int | compute_kernel_args (void *ctl0) |
| int | tune_up_fd (int ctx_fd) |
| static int | attach (void *ctl, unsigned long tid) |
| static int | detach (void *ctx, void *ctl) |
| static int | set_domain (void *ctl0, int domain) |
| static int | set_granularity (void *this_state, int domain) |
| static int | set_inherit (int arg) |
| static int | get_string_from_file (char *file, char *str, int len) |
| int | _papi_pfm_init_component (int cidx) |
| int | _papi_pfm_shutdown_component () |
| static int | _papi_pfm_init_thread (void *thr_ctx) |
| int | _papi_pfm_reset (void *ctx, void *ctl) |
| int | _papi_pfm_write (void *ctx, void *ctl, long long *from) |
| int | _papi_pfm_read (void *ctx0, void *ctl0, long long **events, int flags) |
| int | _papi_pfm_start (void *ctx0, void *ctl0) |
| int | _papi_pfm_stop (void *ctx0, void *ctl0) |
| static int | round_requested_ns (int ns) |
| int | _papi_pfm_ctl (void *ctx, int code, _papi_int_option_t *option) |
| int | _papi_pfm_shutdown (void *ctx0) |
| static int | find_profile_index (EventSetInfo_t *ESI, int pmd, int *flags, unsigned int *native_index, int *profile_index) |
| static void | pfm_bv_set (uint64_t *bv, uint16_t rnum) |
| static int | setup_ear_event (unsigned int native_index, pfarg_pmd_t *pd, int flags) |
| static int | process_smpl_entry (unsigned int native_pfm_index, int flags, pfm_dfl_smpl_entry_t **ent, caddr_t *pc) |
| static int | process_smpl_buf (int num_smpl_pmds, int entry_size, ThreadInfo_t **thr) |
| static void | _papi_pfm_dispatch_timer (int n, void *info, void *uc) |
| static int | _papi_pfm_stop_profiling (ThreadInfo_t *thread, EventSetInfo_t *ESI) |
| static int | _papi_pfm_set_profile (EventSetInfo_t *ESI, int EventIndex, int threshold) |
| static int | _papi_pfm_init_control_state (void *ctl0) |
| static int | _papi_pfm_allocate_registers (EventSetInfo_t *ESI) |
| static int | _papi_pfm_update_control_state (void *ctl0, NativeInfo_t *native, int count, void *ctx0) |
Variables | |
| papi_vector_t | _papi_pfm_vector |
| static int | _perfmon2_pfm_pmu_type = -1 |
| static pfmlib_regmask_t | _perfmon2_pfm_unavailable_pmcs |
| static pfmlib_regmask_t | _perfmon2_pfm_unavailable_pmds |
| #define PFM_MAX_PMCDS 20 |
| static int _papi_pfm_allocate_registers | ( | EventSetInfo_t * | ESI | ) | [static] |
< No error
< No error
< Event exists, but cannot be counted due to counter resource limitations
Definition at line 2112 of file perfmon.c.
{
int i, j;
for ( i = 0; i < ESI->NativeCount; i++ ) {
if ( _papi_libpfm_ntv_code_to_bits
( ESI->NativeInfoArray[i].ni_event,
ESI->NativeInfoArray[i].ni_bits ) != PAPI_OK )
goto bail;
}
return PAPI_OK;
bail:
for ( j = 0; j < i; j++ )
memset( ESI->NativeInfoArray[j].ni_bits, 0x0,
sizeof ( pfm_register_t ) );
return PAPI_ECNFLCT;
}

| int _papi_pfm_ctl | ( | void * | ctx, |
| int | code, | ||
| _papi_int_option_t * | option | ||
| ) |
< Turn on/off or multiplexing for an eventset
< No error
< Attach to a another tid/pid instead of ourself
< Detach
< Domain for an eventset
< Granularity for an eventset
< Option to set the type of itimer used in both software multiplexing, overflowing and profiling
< Invalid argument
< Invalid argument
< Invalid argument
< No error
< Multiplexing/overflowing interval in ns, same as PAPI_DEF_ITIMER_NS
< No error
< Multiplexing/overflowing interval in ns, same as PAPI_DEF_MPX_NS
< No error
< Not supported
Definition at line 1194 of file perfmon.c.
{
switch ( code ) {
case PAPI_MULTIPLEX:
{
option->multiplex.ns = round_requested_ns( option->multiplex.ns );
( ( pfm_control_state_t * ) ( option->multiplex.ESI->ctl_state ) )->
multiplexed = option->multiplex.ns;
return ( PAPI_OK );
}
case PAPI_ATTACH:
return ( attach
( ( pfm_control_state_t * ) ( option->attach.ESI->ctl_state ),
option->attach.tid ) );
case PAPI_DETACH:
return ( detach
( ctx,
( pfm_control_state_t * ) ( option->attach.ESI->
ctl_state ) ) );
case PAPI_DOMAIN:
return ( set_domain
( ( pfm_control_state_t * ) ( option->domain.ESI->ctl_state ),
option->domain.domain ) );
case PAPI_GRANUL:
return ( set_granularity
( ( pfm_control_state_t * ) ( option->granularity.ESI->
ctl_state ),
option->granularity.granularity ) );
#if 0
case PAPI_DATA_ADDRESS:
ret =
set_default_domain( ( pfm_control_state_t * ) ( option->
address_range.ESI->
ctl_state ),
option->address_range.domain );
if ( ret != PAPI_OK )
return ( ret );
set_drange( ctx,
( pfm_control_state_t * ) ( option->address_range.ESI->
ctl_state ), option );
return ( PAPI_OK );
case PAPI_INSTR_ADDRESS:
ret =
set_default_domain( ( pfm_control_state_t * ) ( option->
address_range.ESI->
ctl_state ),
option->address_range.domain );
if ( ret != PAPI_OK )
return ( ret );
set_irange( ctx,
( pfm_control_state_t * ) ( option->address_range.ESI->
ctl_state ), option );
return ( PAPI_OK );
#endif
case PAPI_DEF_ITIMER:
{
/* flags are currently ignored, eventually the flags will be able
to specify whether or not we use POSIX itimers (clock_gettimer) */
if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
( option->itimer.itimer_sig != SIGALRM ) )
return PAPI_EINVAL;
if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
( option->itimer.itimer_sig != SIGVTALRM ) )
return PAPI_EINVAL;
if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
( option->itimer.itimer_sig != SIGPROF ) )
return PAPI_EINVAL;
if ( option->itimer.ns > 0 )
option->itimer.ns = round_requested_ns( option->itimer.ns );
/* At this point, we assume the user knows what he or
she is doing, they maybe doing something arch specific */
return PAPI_OK;
}
case PAPI_DEF_MPX_NS:
{
option->multiplex.ns = round_requested_ns( option->multiplex.ns );
return ( PAPI_OK );
}
case PAPI_DEF_ITIMER_NS:
{
option->itimer.ns = round_requested_ns( option->itimer.ns );
return ( PAPI_OK );
}
default:
return ( PAPI_ENOSUPP );
}
}

| static void _papi_pfm_dispatch_timer | ( | int | n, |
| void * | info, | ||
| void * | uc | ||
| ) | [static] |
< Force using Software
< Using Hardware
< EventSet has profiling enabled
< Force Software overflow in profiling
Definition at line 1734 of file perfmon.c.
{
_papi_hwi_context_t ctx;
#ifdef HAVE_PFM_MSG_TYPE
pfm_msg_t msg;
#else
pfarg_msg_t msg;
#endif
int ret, wanted_fd, fd = info->si_fd;
caddr_t address;
ThreadInfo_t *thread = _papi_hwi_lookup_thread( 0 );
int cidx = _papi_pfm_vector.cmp_info.CmpIdx;
if ( thread == NULL ) {
PAPIERROR( "thread == NULL in _papi_pfm_dispatch_timer!" );
if ( n == _papi_pfm_vector.cmp_info.hardware_intr_sig ) {
ret = read( fd, &msg, sizeof ( msg ) );
pfm_restart( fd );
}
return;
}
if ( thread->running_eventset[cidx] == NULL ) {
PAPIERROR
( "thread->running_eventset == NULL in _papi_pfm_dispatch_timer!" );
if ( n == _papi_pfm_vector.cmp_info.hardware_intr_sig ) {
ret = read( fd, &msg, sizeof ( msg ) );
pfm_restart( fd );
}
return;
}
if ( thread->running_eventset[cidx]->overflow.flags == 0 ) {
PAPIERROR
( "thread->running_eventset->overflow.flags == 0 in _papi_pfm_dispatch_timer!" );
if ( n == _papi_pfm_vector.cmp_info.hardware_intr_sig ) {
ret = read( fd, &msg, sizeof ( msg ) );
pfm_restart( fd );
}
return;
}
ctx.si = info;
ctx.ucontext = ( hwd_ucontext_t * ) uc;
if ( thread->running_eventset[cidx]->overflow.
flags & PAPI_OVERFLOW_FORCE_SW ) {
address = GET_OVERFLOW_ADDRESS( ctx );
_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL,
0, 0, &thread, cidx );
} else {
if ( thread->running_eventset[cidx]->overflow.flags ==
PAPI_OVERFLOW_HARDWARE ) {
wanted_fd =
( ( pfm_control_state_t * ) ( thread->running_eventset[cidx]->
ctl_state ) )->ctx_fd;
} else {
wanted_fd = ( ( pfm_context_t * ) thread->context[cidx] )->ctx_fd;
}
if ( wanted_fd != fd ) {
SUBDBG( "expected fd %d, got %d in _papi_hwi_dispatch_timer!",
wanted_fd, fd );
if ( n == _papi_pfm_vector.cmp_info.hardware_intr_sig ) {
ret = read( fd, &msg, sizeof ( msg ) );
pfm_restart( fd );
}
return;
}
retry:
ret = read( fd, &msg, sizeof ( msg ) );
if ( ret == -1 ) {
if ( errno == EINTR ) {
SUBDBG( "read(%d) interrupted, retrying\n", fd );
goto retry;
} else {
PAPIERROR( "read(%d): errno %d", fd, errno );
}
} else if ( ret != sizeof ( msg ) ) {
PAPIERROR( "read(%d): short %d vs. %d bytes", fd, ret,
sizeof ( msg ) );
ret = -1;
}
if ( msg.type != PFM_MSG_OVFL ) {
PAPIERROR( "unexpected msg type %d", msg.type );
ret = -1;
}
#if 0
if ( msg.pfm_ovfl_msg.msg_ovfl_tid != mygettid( ) ) {
PAPIERROR( "unmatched thread id %lx vs. %lx",
msg.pfm_ovfl_msg.msg_ovfl_tid, mygettid( ) );
ret = -1;
}
#endif
if ( ret != -1 ) {
if ( ( thread->running_eventset[cidx]->state & PAPI_PROFILING ) &&
!( thread->running_eventset[cidx]->profile.
flags & PAPI_PROFIL_FORCE_SW ) )
process_smpl_buf( 0, sizeof ( pfm_dfl_smpl_entry_t ), &thread );
else {
/* PAPI assumes that the overflow vector contains the register index of the
overflowing native event. That is generally true, but Stephane used some
tricks to offset the fixed counters on Core2 (Core? i7?) by 16. This hack
corrects for that hack in a (hopefully) transparent manner */
unsigned long i, vector = msg.pfm_ovfl_msg.msg_ovfl_pmds[0];
pfm_control_state_t *ctl =
( pfm_control_state_t * ) thread->running_eventset[cidx]->
ctl_state;
for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
/* We're only comparing to pmds[0]. A more robust implementation would
compare to pmds[0-3]. The bit mask must be converted to an index
for the comparison to work */
if ( ctl->pd[i].reg_num ==
ffsl( msg.pfm_ovfl_msg.msg_ovfl_pmds[0] ) - 1 ) {
/* if a match is found, convert the index back to a bitmask */
vector = 1 << i;
break;
}
}
_papi_hwi_dispatch_overflow_signal( ( void * ) &ctx,
( caddr_t ) ( ( size_t )
msg.
pfm_ovfl_msg.
msg_ovfl_ip ),
NULL, vector, 0, &thread,
cidx );
}
}
if ( ( ret = pfm_restart( fd ) ) ) {
PAPIERROR( "pfm_restart(%d): %s", fd, strerror( ret ) );
}
}
}

| int _papi_pfm_init_component | ( | int | cidx | ) |
< No error
< No error
< Kernel/OS context counted
< Supervisor/hypervisor context counted
< User context counted
< Kernel/OS context counted
< Supervisor/hypervisor context counted
< Kernel/OS context counted
< Supervisor/hypervisor context counted
< Exception/transient mode (like user TLB misses )
< No error
Definition at line 750 of file perfmon.c.
{
int retval;
char buf[PAPI_HUGE_STR_LEN];
/* The following checks the PFMLIB version
against the perfmon2 kernel version... */
strncpy( _papi_pfm_vector.cmp_info.support_version, buf,
sizeof ( _papi_pfm_vector.cmp_info.support_version ) );
retval = get_string_from_file( "/sys/kernel/perfmon/version",
_papi_pfm_vector.cmp_info.kernel_version,
sizeof ( _papi_pfm_vector.cmp_info.kernel_version ) );
if ( retval != PAPI_OK ) {
strncpy(_papi_pfm_vector.cmp_info.disabled_reason,
"/sys/kernel/perfmon/version not found",PAPI_MAX_STR_LEN);
return retval;
}
#ifdef PFM_VERSION
sprintf( buf, "%d.%d", PFM_VERSION_MAJOR( PFM_VERSION ),
PFM_VERSION_MINOR( PFM_VERSION ) );
SUBDBG( "Perfmon2 library versions...kernel: %s library: %s\n",
_papi_pfm_vector.cmp_info.kernel_version, buf );
if ( strcmp( _papi_pfm_vector.cmp_info.kernel_version, buf ) != 0 ) {
/* do a little exception processing; 81 is compatible with 80 */
if ( !( ( PFM_VERSION_MINOR( PFM_VERSION ) == 81 ) &&
( strncmp( _papi_pfm_vector.cmp_info.kernel_version, "2.8", 3 ) ==
0 ) ) ) {
PAPIERROR( "Version mismatch of libpfm: compiled %s "
"vs. installed %s\n",
buf, _papi_pfm_vector.cmp_info.kernel_version );
return PAPI_ESYS;
}
}
#endif
_papi_pfm_vector.cmp_info.hardware_intr_sig = SIGRTMIN + 2,
/* Run the libpfm-specific setup */
retval=_papi_libpfm_init(&_papi_pfm_vector, cidx);
if (retval) return retval;
/* Load the module, find out if any PMC's/PMD's are off limits */
/* Perfmon2 timeouts are based on the clock tick, we need to check
them otherwise it will complain at us when we multiplex */
unsigned long min_timeout_ns;
struct timespec ts;
if ( syscall( __NR_clock_getres, CLOCK_REALTIME, &ts ) == -1 ) {
PAPIERROR( "Could not detect proper HZ rate, multiplexing may fail\n" );
min_timeout_ns = 10000000;
} else {
min_timeout_ns = ts.tv_nsec;
}
/* This will fail if we've done timeout detection wrong */
retval=detect_timeout_and_unavail_pmu_regs( &_perfmon2_pfm_unavailable_pmcs,
&_perfmon2_pfm_unavailable_pmds,
&min_timeout_ns );
if ( retval != PAPI_OK ) {
return ( retval );
}
if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_IBM ) {
/* powerpc */
_papi_pfm_vector.cmp_info.available_domains |= PAPI_DOM_KERNEL |
PAPI_DOM_SUPERVISOR;
if (strcmp(_papi_hwi_system_info.hw_info.model_string, "POWER6" ) == 0) {
_papi_pfm_vector.cmp_info.default_domain = PAPI_DOM_USER |
PAPI_DOM_KERNEL |
PAPI_DOM_SUPERVISOR;
}
} else {
_papi_pfm_vector.cmp_info.available_domains |= PAPI_DOM_KERNEL;
}
if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_SUN ) {
switch ( _perfmon2_pfm_pmu_type ) {
#ifdef PFMLIB_SPARC_ULTRA12_PMU
case PFMLIB_SPARC_ULTRA12_PMU:
case PFMLIB_SPARC_ULTRA3_PMU:
case PFMLIB_SPARC_ULTRA3I_PMU:
case PFMLIB_SPARC_ULTRA3PLUS_PMU:
case PFMLIB_SPARC_ULTRA4PLUS_PMU:
break;
#endif
default:
_papi_pfm_vector.cmp_info.available_domains |=
PAPI_DOM_SUPERVISOR;
break;
}
}
if ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_CRAY ) {
_papi_pfm_vector.cmp_info.available_domains |= PAPI_DOM_OTHER;
}
if ( ( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_INTEL ) ||
( _papi_hwi_system_info.hw_info.vendor == PAPI_VENDOR_AMD ) ) {
_papi_pfm_vector.cmp_info.fast_counter_read = 1;
_papi_pfm_vector.cmp_info.fast_real_timer = 1;
_papi_pfm_vector.cmp_info.cntr_umasks = 1;
}
return PAPI_OK;
}

| static int _papi_pfm_init_control_state | ( | void * | ctl0 | ) | [static] |
< No error
Definition at line 2087 of file perfmon.c.
{
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
pfmlib_input_param_t *inp = &ctl->in;
pfmlib_output_param_t *outp = &ctl->out;
pfarg_pmd_t *pd = ctl->pd;
pfarg_pmc_t *pc = ctl->pc;
pfarg_setdesc_t *set = ctl->set;
pfarg_setinfo_t *setinfo = ctl->setinfo;
memset( inp, 0, sizeof ( *inp ) );
memset( outp, 0, sizeof ( *inp ) );
memset( pc, 0, sizeof ( ctl->pc ) );
memset( pd, 0, sizeof ( ctl->pd ) );
memset( set, 0, sizeof ( ctl->set ) );
memset( setinfo, 0, sizeof ( ctl->setinfo ) );
/* Will be filled by update now...until this gets another arg */
ctl->ctx = NULL;
ctl->ctx_fd = -1;
ctl->load = NULL;
set_domain( ctl, _papi_pfm_vector.cmp_info.default_domain );
return ( PAPI_OK );
}

| static int _papi_pfm_init_thread | ( | void * | thr_ctx | ) | [static] |
< A System/C library call failed
< No error
Definition at line 869 of file perfmon.c.
{
pfarg_load_t load_args;
pfarg_ctx_t newctx;
int ret, ctx_fd;
#if defined(USE_PROC_PTTIMER)
ret = init_proc_thread_timer( thr_ctx );
if ( ret != PAPI_OK )
return ( ret );
#endif
memset( &newctx, 0, sizeof ( newctx ) );
memset( &load_args, 0, sizeof ( load_args ) );
if ( ( ret = pfm_create_context( &newctx, NULL, NULL, 0 ) ) == -1 ) {
PAPIERROR( "pfm_create_context(): %s",
strerror( errno ) );
return ( PAPI_ESYS );
}
SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", ret );
tune_up_fd( ret );
ctx_fd = ret;
memcpy( &( ( pfm_context_t * ) thr_ctx )->ctx, &newctx, sizeof ( newctx ) );
( ( pfm_context_t * ) thr_ctx )->ctx_fd = ctx_fd;
load_args.load_pid = mygettid( );
memcpy( &( ( pfm_context_t * ) thr_ctx )->load, &load_args,
sizeof ( load_args ) );
return ( PAPI_OK );
}

| int _papi_pfm_read | ( | void * | ctx0, |
| void * | ctl0, | ||
| long long ** | events, | ||
| int | flags | ||
| ) |
< No error
< A System/C library call failed
< No error
< A System/C library call failed
< No error
Definition at line 960 of file perfmon.c.
{
( void ) flags; /*unused */
unsigned int i;
int ret;
long long tot_runs = 0LL;
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
ret = _papi_pfm_read_pmds( ctx, ctl );
if ( ret != PAPI_OK )
return PAPI_ESYS;
/* Copy the values over */
for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
if ( ctl->pd[i].reg_flags & PFM_REGFL_OVFL_NOTIFY )
ctl->counts[i] = ctl->pd[i].reg_value - ctl->pd[i].reg_long_reset;
else
ctl->counts[i] = ctl->pd[i].reg_value;
SUBDBG( "PMD[%d] = %lld (LLD),%llu (LLU)\n", i,
( unsigned long long ) ctl->counts[i],
( unsigned long long ) ctl->pd[i].reg_value );
}
*events = ctl->counts;
/* If we're not multiplexing, bail now */
if ( ctl->num_sets == 1 )
return ( PAPI_OK );
/* If we're multiplexing, get the scaling information */
SUBDBG( "PFM_GETINFO_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, ctl->setinfo,
ctl->num_sets );
if ( ( ret =
pfm_getinfo_evtsets( ctl->ctx_fd, ctl->setinfo, ctl->num_sets ) ) ) {
DEBUGCALL( DEBUG_SUBSTRATE,
dump_setinfo( ctl->setinfo, ctl->num_sets ) );
PAPIERROR( "pfm_getinfo_evtsets(%d,%p,%d): %s", ctl->ctx_fd,
ctl->setinfo, ctl->num_sets, strerror( ret ) );
*events = NULL;
return ( PAPI_ESYS );
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_setinfo( ctl->setinfo, ctl->num_sets ) );
/* Add up the number of total runs */
for ( i = 0; i < ( unsigned int ) ctl->num_sets; i++ )
tot_runs += ctl->setinfo[i].set_runs;
/* Now scale the values */
for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
SUBDBG
( "Counter %d is in set %d ran %llu of %llu times, old count %lld.\n",
i, ctl->pd[i].reg_set,
( unsigned long long ) ctl->setinfo[ctl->pd[i].reg_set].set_runs,
( unsigned long long ) tot_runs, ctl->counts[i] );
if ( ctl->setinfo[ctl->pd[i].reg_set].set_runs )
ctl->counts[i] =
( ctl->counts[i] * tot_runs ) /
ctl->setinfo[ctl->pd[i].reg_set].set_runs;
else {
ctl->counts[i] = 0;
SUBDBG( "Set %lld didn't run!!!!\n",
( unsigned long long ) ctl->pd[i].reg_set );
}
SUBDBG( "Counter %d, new count %lld.\n", i, ctl->counts[i] );
}
return PAPI_OK;
}

| int _papi_pfm_read_pmds | ( | pfm_context_t * | ctx, |
| pfm_control_state_t * | ctl | ||
| ) |
< Access to the counters was lost or interrupted
< A System/C library call failed
< Access to the counters was lost or interrupted
< A System/C library call failed
< No error
Definition at line 266 of file perfmon.c.
{
( void ) ctx; /*unused */
unsigned int i = 0;
int ret;
SUBDBG( "PFM_READ_PMDS(%d,%p,%d)\n", ctl->ctx_fd, ctl->pd,
ctl->in.pfp_event_count );
if ( ctl->in.pfp_event_count > PFM_MAX_PMCDS ) {
for ( i = 0; i < ctl->in.pfp_event_count - PFM_MAX_PMCDS;
i += PFM_MAX_PMCDS ) {
if ( ( ret =
pfm_read_pmds( ctl->ctx_fd, ctl->pd + i,
PFM_MAX_PMCDS ) ) ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmd( ctl ) );
PAPIERROR( "pfm_read_pmds(%d,%p,%d): %s", ctl->ctx_fd, ctl->pd,
ctl->in.pfp_event_count, strerror( ret ) );
return ( ( errno == EBADF ) ? PAPI_ECLOST : PAPI_ESYS );
}
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmd( ctl ) );
}
if ( ( ret =
pfm_read_pmds( ctl->ctx_fd, ctl->pd + i,
ctl->in.pfp_event_count - i ) ) ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmd( ctl ) );
PAPIERROR( "pfm_read_pmds(%d,%p,%d): %s", ctl->ctx_fd, ctl->pd,
ctl->in.pfp_event_count, strerror( ret ) );
return ( ( errno == EBADF ) ? PAPI_ECLOST : PAPI_ESYS );
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmd( ctl ) );
return PAPI_OK;
}


| int _papi_pfm_reset | ( | void * | ctx, |
| void * | ctl | ||
| ) |
< No error
< A System/C library call failed
< No error
Definition at line 904 of file perfmon.c.
{
unsigned int i;
int ret;
/* Read could have clobbered the values */
for ( i = 0; i < ( ( pfm_control_state_t * ) ctl )->in.pfp_event_count;
i++ ) {
if ( ( ( pfm_control_state_t * ) ctl )->pd[i].
reg_flags & PFM_REGFL_OVFL_NOTIFY )
( ( pfm_control_state_t * ) ctl )->pd[i].reg_value =
( ( pfm_control_state_t * ) ctl )->pd[i].reg_long_reset;
else
( ( pfm_control_state_t * ) ctl )->pd[i].reg_value = 0ULL;
}
ret =
_papi_pfm_write_pmds( ( pfm_context_t * ) ctx,
( pfm_control_state_t * ) ctl );
if ( ret != PAPI_OK )
return PAPI_ESYS;
return ( PAPI_OK );
}

| static int _papi_pfm_set_overflow | ( | EventSetInfo_t * | ESI, |
| int | EventIndex, | ||
| int | threshold | ||
| ) | [static] |
< No error
< Invalid argument
< No error
< No error
Definition at line 2005 of file perfmon.c.
{
pfm_control_state_t *this_state =
( pfm_control_state_t * ) ( ESI->ctl_state );
int j, retval = PAPI_OK, *pos;
/* Which counter are we on, this looks suspicious because of the pos[0],
but this could be because of derived events. We should do more here
to figure out exactly what the position is, because the event may
actually have more than one position. */
pos = ESI->EventInfoArray[EventIndex].pos;
j = pos[0];
SUBDBG( "Hardware counter %d used in overflow, threshold %d\n", j,
threshold );
if ( threshold == 0 ) {
/* If this counter isn't set to overflow */
if ( ( this_state->pd[j].reg_flags & PFM_REGFL_OVFL_NOTIFY ) == 0 )
return ( PAPI_EINVAL );
/* Remove the signal handler */
retval = _papi_hwi_stop_signal( _papi_pfm_vector.cmp_info.hardware_intr_sig );
if ( retval != PAPI_OK )
return ( retval );
/* Disable overflow */
this_state->pd[j].reg_flags ^= PFM_REGFL_OVFL_NOTIFY;
/*
* we may want to reset the other PMDs on
* every overflow. If we do not set
* this, the non-overflowed counters
* will be untouched.
if (inp.pfp_event_count > 1)
this_state->pd[j].reg_reset_pmds[0] ^= 1UL << counter_to_reset */
/* Clear the overflow period */
this_state->pd[j].reg_value = 0;
this_state->pd[j].reg_long_reset = 0;
this_state->pd[j].reg_short_reset = 0;
this_state->pd[j].reg_random_seed = 0;
this_state->pd[j].reg_random_mask = 0;
} else {
/* Enable the signal handler */
retval =
_papi_hwi_start_signal( _papi_pfm_vector.cmp_info.hardware_intr_sig, 1,
_papi_pfm_vector.cmp_info.CmpIdx );
if ( retval != PAPI_OK )
return ( retval );
/* Set it to overflow */
this_state->pd[j].reg_flags |= PFM_REGFL_OVFL_NOTIFY;
/*
* we may want to reset the other PMDs on
* every overflow. If we do not set
* this, the non-overflowed counters
* will be untouched.
if (inp.pfp_event_count > 1)
this_state->pd[j].reg_reset_pmds[0] |= 1UL << counter_to_reset */
/* Set the overflow period */
this_state->pd[j].reg_value = -( unsigned long long ) threshold + 1;
this_state->pd[j].reg_short_reset =
-( unsigned long long ) threshold + 1;
this_state->pd[j].reg_long_reset =
-( unsigned long long ) threshold + 1;
}
return ( retval );
}


| static int _papi_pfm_set_profile | ( | EventSetInfo_t * | ESI, |
| int | EventIndex, | ||
| int | threshold | ||
| ) | [static] |
< EventSet has overflowing enabled
< Using Hardware
< A System/C library call failed
< A System/C library call failed
< A System/C library call failed
< No error
< Use data address register profiling
< Use instruction address register profiling
< Drop a random 25% of the samples.
< No error
Definition at line 1879 of file perfmon.c.
{
int cidx = _papi_pfm_vector.cmp_info.CmpIdx;
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ( ESI->ctl_state );
pfm_context_t *ctx = ( pfm_context_t * ) ( ESI->master->context[cidx] );
pfarg_ctx_t newctx;
void *buf_addr = NULL;
pfm_dfl_smpl_arg_t buf_arg;
pfm_dfl_smpl_hdr_t *hdr;
int i, ret, ctx_fd;
memset( &newctx, 0, sizeof ( newctx ) );
if ( threshold == 0 ) {
SUBDBG( "MUNMAP(%p,%lld)\n", ctx->smpl_buf,
( unsigned long long ) ctx->smpl.buf_size );
munmap( ctx->smpl_buf, ctx->smpl.buf_size );
i = close( ctl->ctx_fd );
SUBDBG( "CLOSE fd %d returned %d\n", ctl->ctx_fd, i );
(void) i;
/* Thread has master context */
ctl->ctx_fd = ctx->ctx_fd;
ctl->ctx = &ctx->ctx;
memset( &ctx->smpl, 0, sizeof ( buf_arg ) );
ctx->smpl_buf = NULL;
ret = _papi_pfm_set_overflow( ESI, EventIndex, threshold );
//#warning "This should be handled somewhere else"
ESI->state &= ~( PAPI_OVERFLOWING );
ESI->overflow.flags &= ~( PAPI_OVERFLOW_HARDWARE );
return ( ret );
}
memset( &buf_arg, 0, sizeof ( buf_arg ) );
buf_arg.buf_size = 2 * getpagesize( );
SUBDBG( "PFM_CREATE_CONTEXT(%p,%s,%p,%d)\n", &newctx, PFM_DFL_SMPL_NAME,
&buf_arg, ( int ) sizeof ( buf_arg ) );
if ( ( ret =
pfm_create_context( &newctx, PFM_DFL_SMPL_NAME, &buf_arg,
sizeof ( buf_arg ) ) ) == -1 ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_smpl_arg( &buf_arg ) );
PAPIERROR( "_papi_hwd_set_profile:pfm_create_context(): %s",
strerror( errno ) );
return ( PAPI_ESYS );
}
ctx_fd = ret;
SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", ctx_fd );
tune_up_fd( ret );
SUBDBG( "MMAP(NULL,%lld,%d,%d,%d,0)\n",
( unsigned long long ) buf_arg.buf_size, PROT_READ, MAP_PRIVATE,
ctx_fd );
buf_addr =
mmap( NULL, ( size_t ) buf_arg.buf_size, PROT_READ, MAP_PRIVATE, ctx_fd,
0 );
if ( buf_addr == MAP_FAILED ) {
PAPIERROR( "mmap(NULL,%d,%d,%d,%d,0): %s", buf_arg.buf_size, PROT_READ,
MAP_PRIVATE, ctx_fd, strerror( errno ) );
close( ctx_fd );
return ( PAPI_ESYS );
}
SUBDBG( "Sample buffer is located at %p\n", buf_addr );
hdr = ( pfm_dfl_smpl_hdr_t * ) buf_addr;
SUBDBG( "hdr_cur_offs=%llu version=%u.%u\n",
( unsigned long long ) hdr->hdr_cur_offs,
PFM_VERSION_MAJOR( hdr->hdr_version ),
PFM_VERSION_MINOR( hdr->hdr_version ) );
if ( PFM_VERSION_MAJOR( hdr->hdr_version ) < 1 ) {
PAPIERROR( "invalid buffer format version %d",
PFM_VERSION_MAJOR( hdr->hdr_version ) );
munmap( buf_addr, buf_arg.buf_size );
close( ctx_fd );
return PAPI_ESYS;
}
ret = _papi_pfm_set_overflow( ESI, EventIndex, threshold );
if ( ret != PAPI_OK ) {
munmap( buf_addr, buf_arg.buf_size );
close( ctx_fd );
return ( ret );
}
/* Look up the native event code */
if ( ESI->profile.flags & ( PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR ) ) {
pfarg_pmd_t *pd;
int pos, native_index;
pd = ctl->pd;
pos = ESI->EventInfoArray[EventIndex].pos[0];
native_index =
( ( pfm_register_t * ) ( ESI->NativeInfoArray[pos].ni_bits ) )->
event;
setup_ear_event( native_index, &pd[pos], ESI->profile.flags );
}
if ( ESI->profile.flags & PAPI_PROFIL_RANDOM ) {
pfarg_pmd_t *pd;
int pos;
pd = ctl->pd;
pos = ESI->EventInfoArray[EventIndex].pos[0];
pd[pos].reg_random_seed = 5;
pd[pos].reg_random_mask = 0xff;
}
/* Now close our context it is safe */
// close(ctx->ctx_fd);
/* Copy the new data to the threads context control block */
ctl->ctx_fd = ctx_fd;
memcpy( &ctx->smpl, &buf_arg, sizeof ( buf_arg ) );
ctx->smpl_buf = buf_addr;
return ( PAPI_OK );
}

| int _papi_pfm_shutdown | ( | void * | ctx0 | ) |
< No error
Definition at line 1288 of file perfmon.c.
{
pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
int ret;
#if defined(USE_PROC_PTTIMER)
close( ctx->stat_fd );
#endif
ret = close( ctx->ctx_fd );
SUBDBG( "CLOSE fd %d returned %d\n", ctx->ctx_fd, ret );
(void) ret;
return ( PAPI_OK );
}

| int _papi_pfm_shutdown_component | ( | ) |
| int _papi_pfm_start | ( | void * | ctx0, |
| void * | ctl0 | ||
| ) |
< A System/C library call failed
< No error
< A System/C library call failed
< No error
< A System/C library call failed
< A System/C library call failed
< A System/C library call failed
< No error
Definition at line 1040 of file perfmon.c.
{
unsigned int i;
int ret;
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
#if defined(__crayxt)
if ( _papi_hwd_start_create_context ) {
pfarg_ctx_t tmp;
memset( &tmp, 0, sizeof ( tmp ) );
if ( ( ret = pfm_create_context( &tmp, NULL, NULL, 0 ) ) == -1 ) {
PAPIERROR( "_papi_hwd_init:pfm_create_context(): %s",
strerror( errno ) );
return ( PAPI_ESYS );
}
tune_up_fd( ret );
ctl->ctx_fd = ctx->ctx_fd = ret;
}
#endif /* XT */
if ( ctl->num_sets > 1 ) {
SUBDBG( "PFM_CREATE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, ctl->set,
ctl->num_sets );
if ( ( ret =
pfm_create_evtsets( ctl->ctx_fd, ctl->set,
ctl->num_sets ) ) != PFMLIB_SUCCESS ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( ctl->set, ctl->num_sets ) );
PAPIERROR( "pfm_create_evtsets(%d,%p,%d): errno=%d %s",
ctl->ctx_fd, ctl->set, ctl->num_sets, errno,
strerror( ret ) );
perror( "pfm_create_evtsets" );
return ( PAPI_ESYS );
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( ctl->set, ctl->num_sets ) );
}
/*
* Now program the registers
*
* We don't use the same variable to indicate the number of elements passed to
* the kernel because, as we said earlier, pc may contain more elements than
* the number of events (pmd) we specified, i.e., contains more than counting
* monitors.
*/
ret = _papi_pfm_write_pmcs( ctx, ctl );
if ( ret != PAPI_OK )
return PAPI_ESYS;
/* Set counters to zero as per PAPI_start man page, unless it is set to overflow */
for ( i = 0; i < ctl->in.pfp_event_count; i++ )
if ( !( ctl->pd[i].reg_flags & PFM_REGFL_OVFL_NOTIFY ) )
ctl->pd[i].reg_value = 0ULL;
/*
* To be read, each PMD must be either written or declared
* as being part of a sample (reg_smpl_pmds)
*/
ret = _papi_pfm_write_pmds( ctx, ctl );
if ( ret != PAPI_OK )
return PAPI_ESYS;
SUBDBG( "PFM_LOAD_CONTEXT(%d,%p(%u))\n", ctl->ctx_fd, ctl->load,
ctl->load->load_pid );
if ( ( ret = pfm_load_context( ctl->ctx_fd, ctl->load ) ) ) {
PAPIERROR( "pfm_load_context(%d,%p(%u)): %s", ctl->ctx_fd, ctl->load,
ctl->load->load_pid, strerror( ret ) );
return PAPI_ESYS;
}
SUBDBG( "PFM_START(%d,%p)\n", ctl->ctx_fd, NULL );
if ( ( ret = pfm_start( ctl->ctx_fd, NULL ) ) ) {
PAPIERROR( "pfm_start(%d): %s", ctl->ctx_fd, strerror( ret ) );
return ( PAPI_ESYS );
}
return PAPI_OK;
}

| int _papi_pfm_stop | ( | void * | ctx0, |
| void * | ctl0 | ||
| ) |
< No error
< A System/C library call failed
< A System/C library call failed
< A System/C library call failed
< A System/C library call failed
< No error
Definition at line 1123 of file perfmon.c.
{
( void ) ctx0; /*unused */
int ret;
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
// pfm_context_t *ctx = (pfm_context_t *)ctx0;
SUBDBG( "PFM_STOP(%d)\n", ctl->ctx_fd );
if ( ( ret = pfm_stop( ctl->ctx_fd ) ) ) {
/* If this thread is attached to another thread, and that thread
has exited, we can safely discard the error here. */
if ( ( ret == PFMLIB_ERR_NOTSUPP ) &&
( ctl->load->load_pid != ( unsigned int ) mygettid( ) ) )
return ( PAPI_OK );
PAPIERROR( "pfm_stop(%d): %s", ctl->ctx_fd, strerror( ret ) );
return ( PAPI_ESYS );
}
SUBDBG( "PFM_UNLOAD_CONTEXT(%d) (tid %u)\n", ctl->ctx_fd,
ctl->load->load_pid );
if ( ( ret = pfm_unload_context( ctl->ctx_fd ) ) ) {
PAPIERROR( "pfm_unload_context(%d): %s", ctl->ctx_fd, strerror( ret ) );
return PAPI_ESYS;
}
if ( ctl->num_sets > 1 ) {
static pfarg_setdesc_t set = { 0, 0, 0, 0, {0, 0, 0, 0, 0, 0} };
/* Delete the high sets */
SUBDBG( "PFM_DELETE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, &ctl->set[1],
ctl->num_sets - 1 );
if ( ( ret =
pfm_delete_evtsets( ctl->ctx_fd, &ctl->set[1],
ctl->num_sets - 1 ) ) != PFMLIB_SUCCESS ) {
DEBUGCALL( DEBUG_SUBSTRATE,
dump_sets( &ctl->set[1], ctl->num_sets - 1 ) );
PAPIERROR( "pfm_delete_evtsets(%d,%p,%d): %s", ctl->ctx_fd,
&ctl->set[1], ctl->num_sets - 1, strerror( ret ) );
return ( PAPI_ESYS );
}
DEBUGCALL( DEBUG_SUBSTRATE,
dump_sets( &ctl->set[1], ctl->num_sets - 1 ) );
/* Reprogram the 0 set */
SUBDBG( "PFM_CREATE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, &set, 1 );
if ( ( ret =
pfm_create_evtsets( ctl->ctx_fd, &set,
1 ) ) != PFMLIB_SUCCESS ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( &set, 1 ) );
PAPIERROR( "pfm_create_evtsets(%d,%p,%d): %s", ctl->ctx_fd, &set,
ctl->num_sets, strerror( ret ) );
return ( PAPI_ESYS );
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( &set, 1 ) );
}
return PAPI_OK;
}

| static int _papi_pfm_stop_profiling | ( | ThreadInfo_t * | thread, |
| EventSetInfo_t * | ESI | ||
| ) | [static] |
Definition at line 1871 of file perfmon.c.
{
( void ) ESI; /*unused */
/* Process any remaining samples in the sample buffer */
return ( process_smpl_buf( 0, sizeof ( pfm_dfl_smpl_entry_t ), &thread ) );
}

| static int _papi_pfm_update_control_state | ( | void * | ctl0, |
| NativeInfo_t * | native, | ||
| int | count, | ||
| void * | ctx0 | ||
| ) | [static] |
< No error
< No error
< No error
Definition at line 2134 of file perfmon.c.
{
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
int i = 0, ret;
int last_reg_set = 0, reg_set_done = 0, offset = 0;
pfmlib_input_param_t tmpin, *inp = &ctl->in;
pfmlib_output_param_t tmpout, *outp = &ctl->out;
pfarg_pmd_t *pd = ctl->pd;
if ( count == 0 ) {
SUBDBG( "Called with count == 0\n" );
inp->pfp_event_count = 0;
outp->pfp_pmc_count = 0;
memset( inp->pfp_events, 0x0, sizeof ( inp->pfp_events ) );
return ( PAPI_OK );
}
memcpy( &tmpin, inp, sizeof ( tmpin ) );
memcpy( &tmpout, outp, sizeof ( tmpout ) );
for ( i = 0; i < count; i++ ) {
SUBDBG
( "Stuffing native event index %d (code 0x%x) into input structure.\n",
i, ( ( pfm_register_t * ) native[i].ni_bits )->event );
memcpy( inp->pfp_events + i, native[i].ni_bits,
sizeof ( pfmlib_event_t ) );
}
inp->pfp_event_count = count;
/* let the library figure out the values for the PMCS */
ret = compute_kernel_args( ctl );
if ( ret != PAPI_OK ) {
/* Restore values */
memcpy( inp, &tmpin, sizeof ( tmpin ) );
memcpy( outp, &tmpout, sizeof ( tmpout ) );
return ( ret );
}
/* Update the native structure, because the allocation is done here. */
last_reg_set = pd[0].reg_set;
for ( i = 0; i < count; i++ ) {
if ( pd[i].reg_set != last_reg_set ) {
offset += reg_set_done;
reg_set_done = 0;
}
reg_set_done++;
native[i].ni_position = i;
SUBDBG( "native event index %d (code 0x%x) is at PMD offset %d\n", i,
( ( pfm_register_t * ) native[i].ni_bits )->event,
native[i].ni_position );
}
/* If structure has not yet been filled with a context, fill it
from the thread's context. This should happen in init_control_state
when we give that a *ctx argument */
if ( ctl->ctx == NULL ) {
ctl->ctx = &ctx->ctx;
ctl->ctx_fd = ctx->ctx_fd;
ctl->load = &ctx->load;
}
return ( PAPI_OK );
}

| int _papi_pfm_write | ( | void * | ctx, |
| void * | ctl, | ||
| long long * | from | ||
| ) |
< No error
< A System/C library call failed
< No error
Definition at line 931 of file perfmon.c.
{
unsigned int i;
int ret;
/* Read could have clobbered the values */
for ( i = 0; i < ( ( pfm_control_state_t * ) ctl )->in.pfp_event_count;
i++ ) {
if ( ( ( pfm_control_state_t * ) ctl )->pd[i].
reg_flags & PFM_REGFL_OVFL_NOTIFY )
( ( pfm_control_state_t * ) ctl )->pd[i].reg_value =
from[i] +
( ( pfm_control_state_t * ) ctl )->pd[i].reg_long_reset;
else
( ( pfm_control_state_t * ) ctl )->pd[i].reg_value = from[i];
}
ret =
_papi_pfm_write_pmds( ( pfm_context_t * ) ctx,
( pfm_control_state_t * ) ctl );
if ( ret != PAPI_OK )
return PAPI_ESYS;
return ( PAPI_OK );
}

| int _papi_pfm_write_pmcs | ( | pfm_context_t * | ctx, |
| pfm_control_state_t * | ctl | ||
| ) |
< A System/C library call failed
< A System/C library call failed
< No error
Definition at line 191 of file perfmon.c.
{
( void ) ctx; /*unused */
unsigned int i = 0;
int ret;
SUBDBG( "PFM_WRITE_PMCS(%d,%p,%d)\n", ctl->ctx_fd, ctl->pc,
ctl->out.pfp_pmc_count );
if ( ctl->out.pfp_pmc_count > PFM_MAX_PMCDS ) {
for ( i = 0; i < ctl->out.pfp_pmc_count - PFM_MAX_PMCDS;
i += PFM_MAX_PMCDS ) {
if ( ( ret =
pfm_write_pmcs( ctl->ctx_fd, ctl->pc + i,
PFM_MAX_PMCDS ) ) ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmc( ctl ) );
PAPIERROR( "pfm_write_pmcs(%d,%p,%d): %s", ctl->ctx_fd, ctl->pc,
ctl->out.pfp_pmc_count, strerror( ret ) );
return ( PAPI_ESYS );
}
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmc( ctl ) );
}
if ( ( ret =
pfm_write_pmcs( ctl->ctx_fd, ctl->pc + i,
ctl->out.pfp_pmc_count - i ) ) ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmc( ctl ) );
PAPIERROR( "pfm_write_pmcs(%d,%p,%d): %s", ctl->ctx_fd, ctl->pc,
ctl->out.pfp_pmc_count, strerror( ret ) );
return ( PAPI_ESYS );
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmc( ctl ) );
return PAPI_OK;
}


| int _papi_pfm_write_pmds | ( | pfm_context_t * | ctx, |
| pfm_control_state_t * | ctl | ||
| ) |
< A System/C library call failed
< A System/C library call failed
< No error
Definition at line 227 of file perfmon.c.
{
( void ) ctx; /*unused */
unsigned int i = 0;
int ret;
SUBDBG( "PFM_WRITE_PMDS(%d,%p,%d)\n", ctl->ctx_fd, ctl->pd,
ctl->in.pfp_event_count );
if ( ctl->in.pfp_event_count > PFM_MAX_PMCDS ) {
for ( i = 0; i < ctl->in.pfp_event_count - PFM_MAX_PMCDS;
i += PFM_MAX_PMCDS ) {
if ( ( ret =
pfm_write_pmds( ctl->ctx_fd, ctl->pd + i,
PFM_MAX_PMCDS ) ) ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmd( ctl ) );
PAPIERROR( "pfm_write_pmds(%d,%p,%d): errno=%d %s", ctl->ctx_fd,
ctl->pd, ctl->in.pfp_event_count, errno,
strerror( ret ) );
perror( "pfm_write_pmds" );
return ( PAPI_ESYS );
}
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmd( ctl ) );
}
if ( ( ret =
pfm_write_pmds( ctl->ctx_fd, ctl->pd + i,
ctl->in.pfp_event_count - i ) ) ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmd( ctl ) );
PAPIERROR( "pfm_write_pmds(%d,%p,%d): errno=%d %s", ctl->ctx_fd,
ctl->pd, ctl->in.pfp_event_count, errno, strerror( ret ) );
perror( "pfm_write_pmds" );
return ( PAPI_ESYS );
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_pmd( ctl ) );
return PAPI_OK;
}


| static int attach | ( | void * | ctl, |
| unsigned long | tid | ||
| ) | [static] |
< Insufficient memory
< Invalid argument
< Invalid argument
< A System/C library call failed
< No error
Definition at line 593 of file perfmon.c.
{
pfarg_ctx_t *newctx = ( pfarg_ctx_t * ) malloc( sizeof ( pfarg_ctx_t ) );
pfarg_load_t *load_args =
( pfarg_load_t * ) malloc( sizeof ( pfarg_load_t ) );
int ret;
if ( ( newctx == NULL ) || ( load_args == NULL ) )
return ( PAPI_ENOMEM );
memset( newctx, 0x0, sizeof ( *newctx ) );
memset( load_args, 0, sizeof ( *load_args ) );
/* Make sure the process exists and is being ptraced() */
ret = ptrace( PTRACE_ATTACH, tid, NULL, NULL );
if ( ret == 0 ) {
ptrace( PTRACE_DETACH, tid, NULL, NULL );
PAPIERROR( "Process/thread %d is not being ptraced", tid );
free( newctx );
free( load_args );
return ( PAPI_EINVAL );
}
/* If we get here, then we should hope that the process is being
ptraced, if not, then we probably can't attach to it. */
if ( ( ret == -1 ) && ( errno != EPERM ) ) {
PAPIERROR( "Process/thread %d cannot be ptraced: %s", tid,
strerror( errno ) );
free( newctx );
free( load_args );
return ( PAPI_EINVAL );
}
SUBDBG( "PFM_CREATE_CONTEXT(%p,%p,%p,%d)\n", newctx, NULL, NULL, 0 );
if ( ( ret = pfm_create_context( newctx, NULL, NULL, 0 ) ) == -1 ) {
PAPIERROR( "attach:pfm_create_context(): %s", strerror( errno ) );
free( newctx );
free( load_args );
return ( PAPI_ESYS );
}
SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", ret );
tune_up_fd( ret );
( ( pfm_control_state_t * ) ctl )->ctx_fd = ret;
( ( pfm_control_state_t * ) ctl )->ctx = newctx;
load_args->load_pid = tid;
( ( pfm_control_state_t * ) ctl )->load = load_args;
return ( PAPI_OK );
}


| static int check_multiplex_timeout | ( | int | ctx_fd, |
| unsigned long * | timeout_ns | ||
| ) | [static] |
< A System/C library call failed
< No error
Definition at line 306 of file perfmon.c.
{
int ret;
pfarg_setdesc_t set[2];
memset( set, 0, sizeof ( pfarg_setdesc_t ) * 2 );
set[1].set_id = 1;
set[1].set_flags = PFM_SETFL_TIME_SWITCH;
set[1].set_timeout = *timeout_ns;
SUBDBG( "Multiplexing interval requested is %llu ns.\n",
( unsigned long long ) set[1].set_timeout );
/* Create a test eventset */
SUBDBG( "PFM_CREATE_EVTSETS(%d,%p,1)\n", ctx_fd, &set[1] );
if ( ( ret = pfm_create_evtsets( ctx_fd, &set[1], 1 ) ) != PFMLIB_SUCCESS ) {
DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( &set[1], 1 ) );
PAPIERROR( "pfm_create_evtsets(%d,%p,%d): %s", ctx_fd, &set[1], 1,
strerror( ret ) );
return ( PAPI_ESYS );
}
SUBDBG( "Multiplexing interval returned is %llu ns.\n",
( unsigned long long ) set[1].set_timeout );
*timeout_ns = set[1].set_timeout;
/* Delete the second eventset */
pfm_delete_evtsets( ctx_fd, &set[1], 1 );
return ( PAPI_OK );
}


| static int compute_kernel_args | ( | void * | ctl0 | ) | [inline, static] |
< No error
Definition at line 400 of file perfmon.c.
{
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
pfmlib_input_param_t *inp = &ctl->in;
pfmlib_output_param_t *outp = &ctl->out;
pfmlib_input_param_t tmpin;
pfmlib_output_param_t tmpout;
#if 0
/* This will be used to fixup the overflow and sample args after re-allocation */
pfarg_pmd_t oldpd;
#endif
pfarg_pmd_t *pd = ctl->pd;
pfarg_pmc_t *pc = ctl->pc;
pfarg_setdesc_t *sets = ctl->set;
pfarg_setinfo_t *setinfos = ctl->setinfo;
int *num_sets = &ctl->num_sets;
unsigned int set = 0;
int donepc = 0, donepd = 0, ret, j;
unsigned int i, dispatch_count = inp->pfp_event_count;
int togo = inp->pfp_event_count, done = 0;
/* Save old PD array so we can reconstruct certain flags. */
/* This can be removed when we have higher level code call */
/* set_profile,set_overflow etc when there is hardware */
/* (component) support, but this change won't happen for PAPI 3.5 */
SUBDBG
( "entry multiplexed %d, pfp_event_count %d, num_cntrs %d, num_sets %d\n",
ctl->multiplexed, inp->pfp_event_count, _papi_pfm_vector.cmp_info.num_cntrs,
*num_sets );
if ( ( ctl->multiplexed ) &&
( inp->pfp_event_count >
( unsigned int ) _papi_pfm_vector.cmp_info.num_cntrs ) ) {
dispatch_count = _papi_pfm_vector.cmp_info.num_cntrs;
}
while ( togo ) {
again:
memset( &tmpin, 0x0, sizeof ( tmpin ) );
memset( &tmpout, 0x0, sizeof ( tmpout ) );
SUBDBG( "togo %d, done %d, dispatch_count %d, num_cntrs %d\n", togo,
done, dispatch_count, _papi_pfm_vector.cmp_info.num_cntrs );
tmpin.pfp_event_count = dispatch_count;
tmpin.pfp_dfl_plm = inp->pfp_dfl_plm;
/* Make sure we tell dispatch that these PMC's are not available */
memcpy( &tmpin.pfp_unavail_pmcs, &_perfmon2_pfm_unavailable_pmcs,
sizeof ( _perfmon2_pfm_unavailable_pmcs ) );
for ( i = 0, j = done; i < dispatch_count; i++, j++ ) {
memcpy( tmpin.pfp_events + i, inp->pfp_events + j,
sizeof ( pfmlib_event_t ) );
}
if ( ( ret =
pfm_dispatch_events( &tmpin, NULL, &tmpout,
NULL ) ) != PFMLIB_SUCCESS ) {
if ( ctl->multiplexed ) {
dispatch_count--;
if ( dispatch_count == 0 ) {
PAPIERROR( "pfm_dispatch_events(): %s",
pfm_strerror( ret ) );
return ( _papi_libpfm_error( ret ) );
}
SUBDBG
( "Dispatch failed because of counter conflict, trying again with %d counters.\n",
dispatch_count );
goto again;
}
PAPIERROR( "pfm_dispatch_events(): %s", pfm_strerror( ret ) );
return ( _papi_libpfm_error( ret ) );
}
/*
* Now prepare the argument to initialize the PMDs and PMCS.
* We must pfp_pmc_count to determine the number of PMC to intialize.
* We must use pfp_event_count to determine the number of PMD to initialize.
* Some events causes extra PMCs to be used, so pfp_pmc_count may be >= pfp_event_count.
*
* This step is new compared to libpfm-2.x. It is necessary because the library no
* longer knows about the kernel data structures.
*/
for ( i = 0; i < tmpout.pfp_pmc_count; i++, donepc++ ) {
pc[donepc].reg_num = tmpout.pfp_pmcs[i].reg_num;
pc[donepc].reg_value = tmpout.pfp_pmcs[i].reg_value;
pc[donepc].reg_set = set;
SUBDBG( "PC%d (i%d) is reg num %d, value %llx, set %d\n", donepc, i,
pc[donepc].reg_num,
( unsigned long long ) pc[donepc].reg_value,
pc[donepc].reg_set );
}
/* figure out pmd mapping from output pmc */
#if defined(HAVE_PFM_REG_EVT_IDX)
for ( i = 0, j = 0; i < tmpin.pfp_event_count; i++, donepd++ ) {
pd[donepd].reg_num = tmpout.pfp_pmcs[j].reg_pmd_num;
pd[donepd].reg_set = set;
SUBDBG( "PD%d (i%d,j%d) is reg num %d, set %d\n", donepd, i, j,
pd[donepd].reg_num, pd[donepd].reg_set );
/* Skip over entries that map to the same PMD,
PIV has 2 PMCS for every PMD */
for ( ; j < tmpout.pfp_pmc_count; j++ )
if ( tmpout.pfp_pmcs[j].reg_evt_idx != i )
break;
}
#else
for ( i = 0; i < tmpout.pfp_pmd_count; i++, donepd++ ) {
pd[donepd].reg_num = tmpout.pfp_pmds[i].reg_num;
pd[donepd].reg_set = set;
SUBDBG( "PD%d (i%d) is reg num %d, set %d\n", donepd, i,
pd[donepd].reg_num, pd[donepd].reg_set );
}
#endif
togo -= dispatch_count;
done += dispatch_count;
if ( togo > _papi_pfm_vector.cmp_info.num_cntrs )
dispatch_count = _papi_pfm_vector.cmp_info.num_cntrs;
else
dispatch_count = togo;
setinfos[set].set_id = set;
sets[set].set_id = set;
set++;
}
*num_sets = set;
outp->pfp_pmc_count = donepc;
if ( ctl->multiplexed && ( set > 1 ) ) {
for ( i = 0; i < set; i++ ) {
sets[i].set_flags = PFM_SETFL_TIME_SWITCH;
sets[i].set_timeout = ctl->multiplexed;
}
}
SUBDBG
( "exit multiplexed %d (ns switch time), pfp_pmc_count %d, num_sets %d\n",
ctl->multiplexed, outp->pfp_pmc_count, *num_sets );
return ( PAPI_OK );
}


| static int detach | ( | void * | ctx, |
| void * | ctl | ||
| ) | [static] |
< No error
Definition at line 645 of file perfmon.c.
{
int i;
i = close( ( ( pfm_control_state_t * ) ctl )->ctx_fd );
SUBDBG( "CLOSE fd %d returned %d\n",
( ( pfm_control_state_t * ) ctl )->ctx_fd, i );
(void) i;
/* Restore to main threads context */
free( ( ( pfm_control_state_t * ) ctl )->ctx );
( ( pfm_control_state_t * ) ctl )->ctx = &( ( pfm_context_t * ) ctx )->ctx;
( ( pfm_control_state_t * ) ctl )->ctx_fd =
( ( pfm_context_t * ) ctx )->ctx_fd;
free( ( ( pfm_control_state_t * ) ctl )->load );
( ( pfm_control_state_t * ) ctl )->load =
&( ( pfm_context_t * ) ctx )->load;
return ( PAPI_OK );
}


| static int detect_timeout_and_unavail_pmu_regs | ( | pfmlib_regmask_t * | r_pmcs, |
| pfmlib_regmask_t * | r_pmds, | ||
| unsigned long * | timeout_ns | ||
| ) | [static] |
< A System/C library call failed
< A System/C library call failed
< No error
Definition at line 341 of file perfmon.c.
{
pfarg_ctx_t ctx;
pfarg_setinfo_t setf;
unsigned int i;
int ret, j, myfd;
memset( r_pmcs, 0, sizeof ( *r_pmcs ) );
memset( r_pmds, 0, sizeof ( *r_pmds ) );
memset( &ctx, 0, sizeof ( ctx ) );
memset( &setf, 0, sizeof ( setf ) );
/*
* if no context descriptor is passed, then create
* a temporary context
*/
SUBDBG( "PFM_CREATE_CONTEXT(%p,%p,%p,%d)\n", &ctx, NULL, NULL, 0 );
myfd = pfm_create_context( &ctx, NULL, NULL, 0 );
if ( myfd == -1 ) {
PAPIERROR( "detect_unavail_pmu_regs:pfm_create_context(): %s",
strerror( errno ) );
return ( PAPI_ESYS );
}
SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", myfd );
/*
* retrieve available register bitmasks from set0
* which is guaranteed to exist for every context
*/
ret = pfm_getinfo_evtsets( myfd, &setf, 1 );
if ( ret != PFMLIB_SUCCESS ) {
PAPIERROR( "pfm_getinfo_evtsets(): %s", strerror( ret ) );
return ( PAPI_ESYS );
}
DEBUGCALL( DEBUG_SUBSTRATE, dump_setinfo( &setf, 1 ) );
if ( r_pmcs )
for ( i = 0; i < PFM_PMC_BV; i++ ) {
for ( j = 0; j < 64; j++ ) {
if ( ( setf.set_avail_pmcs[i] & ( 1ULL << j ) ) == 0 )
pfm_regmask_set( r_pmcs, ( i << 6 ) + j );
}
}
if ( r_pmds )
for ( i = 0; i < PFM_PMD_BV; i++ ) {
for ( j = 0; j < 64; j++ ) {
if ( ( setf.set_avail_pmds[i] & ( 1ULL << j ) ) == 0 )
pfm_regmask_set( r_pmds, ( i << 6 ) + j );
}
}
check_multiplex_timeout( myfd, timeout_ns );
i = close( myfd );
SUBDBG( "CLOSE fd %d returned %d\n", myfd, i );
return PAPI_OK;
}


| static int find_profile_index | ( | EventSetInfo_t * | ESI, |
| int | pmd, | ||
| int * | flags, | ||
| unsigned int * | native_index, | ||
| int * | profile_index | ||
| ) | [inline, static] |
< No error
< Internal error, please send mail to the developers
Definition at line 1307 of file perfmon.c.
{
int pos, esi_index, count;
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ESI->ctl_state;
pfarg_pmd_t *pd;
unsigned int i;
pd = ctl->pd;
/* Find virtual PMD index, the one we actually read from the physical PMD number that
overflowed. This index is the one related to the profile buffer. */
for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
if ( pd[i].reg_num == pmd ) {
SUBDBG( "Physical PMD %d is Virtual PMD %d\n", pmd, i );
pmd = i;
break;
}
}
SUBDBG( "(%p,%d,%p)\n", ESI, pmd, index );
for ( count = 0; count < ESI->profile.event_counter; count++ ) {
/* Find offset of PMD that gets read from the kernel */
esi_index = ESI->profile.EventIndex[count];
pos = ESI->EventInfoArray[esi_index].pos[0];
SUBDBG( "Examining event at ESI index %d, PMD position %d\n", esi_index,
pos );
// PMU_FIRST_COUNTER
if ( pos == pmd ) {
*profile_index = count;
*native_index =
ESI->NativeInfoArray[pos].ni_event & PAPI_NATIVE_AND_MASK;
*flags = ESI->profile.flags;
SUBDBG( "Native event %d is at profile index %d, flags %d\n",
*native_index, *profile_index, *flags );
return ( PAPI_OK );
}
}
PAPIERROR( "wrong count: %d vs. ESI->profile.event_counter %d", count,
ESI->profile.event_counter );
return ( PAPI_EBUG );
}


| static int get_string_from_file | ( | char * | file, |
| char * | str, | ||
| int | len | ||
| ) | [static] |
< A System/C library call failed
< A System/C library call failed
< No error
Definition at line 731 of file perfmon.c.
{
FILE *f = fopen( file, "r" );
char buf[PAPI_HUGE_STR_LEN];
if ( f == NULL ) {
PAPIERROR( "fopen(%s): %s", file, strerror( errno ) );
return ( PAPI_ESYS );
}
if ( fscanf( f, "%s\n", buf ) != 1 ) {
PAPIERROR( "fscanf(%s, %%s\\n): Unable to scan 1 token", file );
fclose( f );
return PAPI_ESYS;
}
strncpy( str, buf, ( len > PAPI_HUGE_STR_LEN ? PAPI_HUGE_STR_LEN : len ) );
fclose( f );
return ( PAPI_OK );
}


| static void pfm_bv_set | ( | uint64_t * | bv, |
| uint16_t | rnum | ||
| ) | [inline, static] |
| static int process_smpl_buf | ( | int | num_smpl_pmds, |
| int | entry_size, | ||
| ThreadInfo_t ** | thr | ||
| ) | [inline, static] |
< No error
< No error
Definition at line 1685 of file perfmon.c.
{
( void ) num_smpl_pmds; /*unused */
( void ) entry_size; /*unused */
int cidx = _papi_pfm_vector.cmp_info.CmpIdx;
pfm_dfl_smpl_entry_t *ent;
uint64_t entry, count;
pfm_dfl_smpl_hdr_t *hdr =
( ( pfm_context_t * ) ( *thr )->context[cidx] )->smpl_buf;
int ret, profile_index, flags;
unsigned int native_pfm_index;
caddr_t pc = NULL;
long long weight;
DEBUGCALL( DEBUG_SUBSTRATE, dump_smpl_hdr( hdr ) );
count = hdr->hdr_count;
ent = ( pfm_dfl_smpl_entry_t * ) ( hdr + 1 );
entry = 0;
SUBDBG( "This buffer has %llu samples in it.\n",
( unsigned long long ) count );
while ( count-- ) {
SUBDBG( "Processing sample entry %llu\n",
( unsigned long long ) entry );
DEBUGCALL( DEBUG_SUBSTRATE, dump_smpl( ent ) );
/* Find the index of the profile buffers if we are profiling on many events */
ret =
find_profile_index( ( *thr )->running_eventset[cidx], ent->ovfl_pmd,
&flags, &native_pfm_index, &profile_index );
if ( ret != PAPI_OK )
return ( ret );
weight = process_smpl_entry( native_pfm_index, flags, &ent, &pc );
_papi_hwi_dispatch_profile( ( *thr )->running_eventset[cidx], pc,
weight, profile_index );
entry++;
}
return ( PAPI_OK );
}


| static int process_smpl_entry | ( | unsigned int | native_pfm_index, |
| int | flags, | ||
| pfm_dfl_smpl_entry_t ** | ent, | ||
| caddr_t * | pc | ||
| ) | [inline, static] |
Definition at line 1443 of file perfmon.c.
{
#ifndef __ia64__
( void ) native_pfm_index; /*unused */
( void ) flags; /*unused */
#endif
SUBDBG( "process_smpl_entry(%d,%d,%p,%p)\n", native_pfm_index, flags, ent,
pc );
#ifdef __ia64__
/* Fixup EAR stuff here */
if ( is_montecito_and_dear( native_pfm_index ) ) {
pfm_mont_pmd_reg_t data_addr;
pfm_mont_pmd_reg_t latency;
pfm_mont_pmd_reg_t load_addr;
unsigned long newent;
if ( ( flags & ( PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR ) ) == 0 )
goto safety;
/* Skip the header */
++( *ent );
// PMD32 has data address on Montecito
// PMD33 has latency on Montecito
// PMD36 has instruction address on Montecito
data_addr = *( pfm_mont_pmd_reg_t * ) * ent;
latency =
*( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
sizeof ( data_addr ) );
load_addr =
*( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
sizeof ( data_addr ) +
sizeof ( latency ) );
SUBDBG( "PMD[32]: 0x%016llx\n",
( unsigned long long ) data_addr.pmd_val );
SUBDBG( "PMD[33]: 0x%016llx\n",
( unsigned long long ) latency.pmd_val );
SUBDBG( "PMD[36]: 0x%016llx\n",
( unsigned long long ) load_addr.pmd_val );
if ( ( !load_addr.pmd36_mont_reg.dear_vl ) ||
( !load_addr.pmd33_mont_reg.dear_stat ) ) {
SUBDBG
( "Invalid DEAR sample found, dear_vl = %d, dear_stat = 0x%x\n",
load_addr.pmd36_mont_reg.dear_vl,
load_addr.pmd33_mont_reg.dear_stat );
bail1:
newent = ( unsigned long ) *ent;
newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
*ent = ( pfm_dfl_smpl_entry_t * ) newent;
return 0;
}
if ( flags & PAPI_PROFIL_DATA_EAR )
*pc = ( caddr_t ) data_addr.pmd_val;
else if ( flags & PAPI_PROFIL_INST_EAR ) {
unsigned long tmp =
( ( load_addr.pmd36_mont_reg.dear_iaddr +
( unsigned long ) load_addr.pmd36_mont_reg.
dear_bn ) << 4 ) | ( unsigned long ) load_addr.
pmd36_mont_reg.dear_slot;
*pc = ( caddr_t ) tmp;
} else {
PAPIERROR( "BUG!" );
goto bail1;
}
newent = ( unsigned long ) *ent;
newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
*ent = ( pfm_dfl_smpl_entry_t * ) newent;
return 0;
} else if ( is_montecito_and_iear( native_pfm_index ) ) {
pfm_mont_pmd_reg_t latency;
pfm_mont_pmd_reg_t icache_line_addr;
unsigned long newent;
if ( ( flags & PAPI_PROFIL_INST_EAR ) == 0 )
goto safety;
/* Skip the header */
++( *ent );
// PMD34 has data address on Montecito
// PMD35 has latency on Montecito
icache_line_addr = *( pfm_mont_pmd_reg_t * ) * ent;
latency =
*( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
sizeof ( icache_line_addr ) );
SUBDBG( "PMD[34]: 0x%016llx\n",
( unsigned long long ) icache_line_addr.pmd_val );
SUBDBG( "PMD[35]: 0x%016llx\n",
( unsigned long long ) latency.pmd_val );
if ( ( icache_line_addr.pmd34_mont_reg.iear_stat & 0x1 ) == 0 ) {
SUBDBG( "Invalid IEAR sample found, iear_stat = 0x%x\n",
icache_line_addr.pmd34_mont_reg.iear_stat );
bail2:
newent = ( unsigned long ) *ent;
newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
*ent = ( pfm_dfl_smpl_entry_t * ) newent;
return ( 0 );
}
if ( flags & PAPI_PROFIL_INST_EAR ) {
unsigned long tmp = icache_line_addr.pmd34_mont_reg.iear_iaddr << 5;
*pc = ( caddr_t ) tmp;
} else {
PAPIERROR( "BUG!" );
goto bail2;
}
newent = ( unsigned long ) *ent;
newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
*ent = ( pfm_dfl_smpl_entry_t * ) newent;
return 0;
} else if ( is_itanium2_and_dear( native_pfm_index ) ) {
pfm_ita2_pmd_reg_t data_addr;
pfm_ita2_pmd_reg_t latency;
pfm_ita2_pmd_reg_t load_addr;
unsigned long newent;
if ( ( flags & ( PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR ) ) == 0 )
goto safety;
/* Skip the header */
++( *ent );
// PMD2 has data address on Itanium 2
// PMD3 has latency on Itanium 2
// PMD17 has instruction address on Itanium 2
data_addr = *( pfm_ita2_pmd_reg_t * ) * ent;
latency =
*( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
sizeof ( data_addr ) );
load_addr =
*( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
sizeof ( data_addr ) +
sizeof ( latency ) );
SUBDBG( "PMD[2]: 0x%016llx\n",
( unsigned long long ) data_addr.pmd_val );
SUBDBG( "PMD[3]: 0x%016llx\n", ( unsigned long long ) latency.pmd_val );
SUBDBG( "PMD[17]: 0x%016llx\n",
( unsigned long long ) load_addr.pmd_val );
if ( ( !load_addr.pmd17_ita2_reg.dear_vl ) ||
( !load_addr.pmd3_ita2_reg.dear_stat ) ) {
SUBDBG
( "Invalid DEAR sample found, dear_vl = %d, dear_stat = 0x%x\n",
load_addr.pmd17_ita2_reg.dear_vl,
load_addr.pmd3_ita2_reg.dear_stat );
bail3:
newent = ( unsigned long ) *ent;
newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
*ent = ( pfm_dfl_smpl_entry_t * ) newent;
return 0;
}
if ( flags & PAPI_PROFIL_DATA_EAR )
*pc = ( caddr_t ) data_addr.pmd_val;
else if ( flags & PAPI_PROFIL_INST_EAR ) {
unsigned long tmp =
( ( load_addr.pmd17_ita2_reg.dear_iaddr +
( unsigned long ) load_addr.pmd17_ita2_reg.
dear_bn ) << 4 ) | ( unsigned long ) load_addr.
pmd17_ita2_reg.dear_slot;
*pc = ( caddr_t ) tmp;
} else {
PAPIERROR( "BUG!" );
goto bail3;
}
newent = ( unsigned long ) *ent;
newent += 3 * sizeof ( pfm_ita2_pmd_reg_t );
*ent = ( pfm_dfl_smpl_entry_t * ) newent;
return 0;
} else if ( is_itanium2_and_iear( native_pfm_index ) ) {
pfm_ita2_pmd_reg_t latency;
pfm_ita2_pmd_reg_t icache_line_addr;
unsigned long newent;
if ( ( flags & PAPI_PROFIL_INST_EAR ) == 0 )
goto safety;
/* Skip the header */
++( *ent );
// PMD0 has address on Itanium 2
// PMD1 has latency on Itanium 2
icache_line_addr = *( pfm_ita2_pmd_reg_t * ) * ent;
latency =
*( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
sizeof ( icache_line_addr ) );
SUBDBG( "PMD[0]: 0x%016llx\n",
( unsigned long long ) icache_line_addr.pmd_val );
SUBDBG( "PMD[1]: 0x%016llx\n", ( unsigned long long ) latency.pmd_val );
if ( ( icache_line_addr.pmd0_ita2_reg.iear_stat & 0x1 ) == 0 ) {
SUBDBG( "Invalid IEAR sample found, iear_stat = 0x%x\n",
icache_line_addr.pmd0_ita2_reg.iear_stat );
bail4:
newent = ( unsigned long ) *ent;
newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
*ent = ( pfm_dfl_smpl_entry_t * ) newent;
return ( 0 );
}
if ( flags & PAPI_PROFIL_INST_EAR ) {
unsigned long tmp = icache_line_addr.pmd0_ita2_reg.iear_iaddr << 5;
*pc = ( caddr_t ) tmp;
} else {
PAPIERROR( "BUG!" );
goto bail4;
}
newent = ( unsigned long ) *ent;
newent += 2 * sizeof ( pfm_ita2_pmd_reg_t );
*ent = ( pfm_dfl_smpl_entry_t * ) newent;
return 0;
}
#if 0
( is_btb( native_pfm_index ) ) {
// PMD48-63,39 on Montecito
// PMD8-15,16 on Itanium 2
}
#endif
else
safety:
#endif
{
*pc = ( caddr_t ) ( ( size_t ) ( ( *ent )->ip ) );
++( *ent );
return ( 0 );
}
}


| static int round_requested_ns | ( | int | ns | ) | [inline, static] |
Definition at line 1183 of file perfmon.c.
{
if ( ns <= _papi_os_info.itimer_res_ns ) {
return _papi_os_info.itimer_res_ns;
} else {
int leftover_ns = ns % _papi_os_info.itimer_res_ns;
return ( ns - leftover_ns + _papi_os_info.itimer_res_ns );
}
}

| static int set_domain | ( | void * | ctl0, |
| int | domain | ||
| ) | [inline, static] |
< User context counted
< Kernel/OS context counted
< Supervisor/hypervisor context counted
< Exception/transient mode (like user TLB misses )
< Invalid argument
Definition at line 667 of file perfmon.c.
{
pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
int mode = 0, did = 0;
pfmlib_input_param_t *inp = &ctl->in;
if ( domain & PAPI_DOM_USER ) {
did = 1;
mode |= PFM_PLM3;
}
if ( domain & PAPI_DOM_KERNEL ) {
did = 1;
mode |= PFM_PLM0;
}
if ( domain & PAPI_DOM_SUPERVISOR ) {
did = 1;
mode |= PFM_PLM1;
}
if ( domain & PAPI_DOM_OTHER ) {
did = 1;
mode |= PFM_PLM2;
}
if ( !did )
return ( PAPI_EINVAL );
inp->pfp_dfl_plm = mode;
return ( compute_kernel_args( ctl ) );
}


| static int set_granularity | ( | void * | this_state, |
| int | domain | ||
| ) | [inline, static] |
< PAPI counters for each individual process group
< PAPI counters for the current CPU, are you bound?
< PAPI counters for all CPUs individually
< PAPI counters for each individual process
< Not supported by component
< PAPI counters for each individual thread
< Invalid argument
< No error
Definition at line 702 of file perfmon.c.
{
( void ) this_state; /*unused */
switch ( domain ) {
case PAPI_GRN_PROCG:
case PAPI_GRN_SYS:
case PAPI_GRN_SYS_CPU:
case PAPI_GRN_PROC:
return PAPI_ECMP;
case PAPI_GRN_THR:
break;
default:
return PAPI_EINVAL;
}
return PAPI_OK;
}

| static int set_inherit | ( | int | arg | ) | [inline, static] |
| static int setup_ear_event | ( | unsigned int | native_index, |
| pfarg_pmd_t * | pd, | ||
| int | flags | ||
| ) | [inline, static] |
Definition at line 1402 of file perfmon.c.
{
( void ) flags; /*unused */
#if defined(__ia64__)
if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU ) {
if ( pfm_mont_is_dear( native_index ) ) { /* 2,3,17 */
pfm_bv_set( pd[0].reg_smpl_pmds, 32 );
pfm_bv_set( pd[0].reg_smpl_pmds, 33 );
pfm_bv_set( pd[0].reg_smpl_pmds, 36 );
pfm_bv_set( pd[0].reg_reset_pmds, 36 );
return ( 1 );
} else if ( pfm_mont_is_iear( native_index ) ) { /* O,1 MK */
pfm_bv_set( pd[0].reg_smpl_pmds, 34 );
pfm_bv_set( pd[0].reg_smpl_pmds, 35 );
pfm_bv_set( pd[0].reg_reset_pmds, 34 );
return ( 1 );
}
return ( 0 );
} else if ( _perfmon2_pfm_pmu_type == PFMLIB_ITANIUM2_PMU ) {
if ( pfm_mont_is_dear( native_index ) ) { /* 2,3,17 */
pfm_bv_set( pd[0].reg_smpl_pmds, 2 );
pfm_bv_set( pd[0].reg_smpl_pmds, 3 );
pfm_bv_set( pd[0].reg_smpl_pmds, 17 );
pfm_bv_set( pd[0].reg_reset_pmds, 17 );
return ( 1 );
} else if ( pfm_mont_is_iear( native_index ) ) { /* O,1 MK */
pfm_bv_set( pd[0].reg_smpl_pmds, 0 );
pfm_bv_set( pd[0].reg_smpl_pmds, 1 );
pfm_bv_set( pd[0].reg_reset_pmds, 0 );
return ( 1 );
}
return ( 0 );
}
#else
( void ) native_index; /*unused */
( void ) pd; /*unused */
#endif
return ( 0 );
}


| int tune_up_fd | ( | int | ctx_fd | ) |
< A System/C library call failed
< A System/C library call failed
< A System/C library call failed
< A System/C library call failed
< No error
Definition at line 547 of file perfmon.c.
{
int ret;
/* set close-on-exec to ensure we will be getting the PFM_END_MSG, i.e.,
* fd not visible to child. */
ret = fcntl( ctx_fd, F_SETFD, FD_CLOEXEC );
if ( ret == -1 ) {
PAPIERROR( "cannot fcntl(FD_CLOEXEC) on %d: %s", ctx_fd,
strerror( errno ) );
return ( PAPI_ESYS );
}
/* setup asynchronous notification on the file descriptor */
ret = fcntl( ctx_fd, F_SETFL, fcntl( ctx_fd, F_GETFL, 0 ) | O_ASYNC );
if ( ret == -1 ) {
PAPIERROR( "cannot fcntl(O_ASYNC) on %d: %s", ctx_fd,
strerror( errno ) );
return ( PAPI_ESYS );
}
/* get ownership of the descriptor */
ret = fcntl( ctx_fd, F_SETOWN, mygettid( ) );
if ( ret == -1 ) {
PAPIERROR( "cannot fcntl(F_SETOWN) on %d: %s", ctx_fd,
strerror( errno ) );
return ( PAPI_ESYS );
}
/*
* when you explicitely declare that you want a particular signal,
* even with you use the default signal, the kernel will send more
* information concerning the event to the signal handler.
*
* In particular, it will send the file descriptor from which the
* event is originating which can be quite useful when monitoring
* multiple tasks from a single thread.
*/
ret = fcntl( ctx_fd, F_SETSIG, _papi_pfm_vector.cmp_info.hardware_intr_sig );
if ( ret == -1 ) {
PAPIERROR( "cannot fcntl(F_SETSIG,%d) on %d: %s",
_papi_pfm_vector.cmp_info.hardware_intr_sig, ctx_fd,
strerror( errno ) );
return ( PAPI_ESYS );
}
return ( PAPI_OK );
}


int _perfmon2_pfm_pmu_type = -1 [static] |
pfmlib_regmask_t _perfmon2_pfm_unavailable_pmcs [static] |
pfmlib_regmask_t _perfmon2_pfm_unavailable_pmds [static] |