PAPI 7.1.0.0
Loading...
Searching...
No Matches
perfmon2/perfmon.c File Reference
Include dependency graph for perfmon2/perfmon.c:

Go to the source code of this file.

Macros

#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)
 
static void dump_smpl_arg (pfm_dfl_smpl_arg_t *arg)
 
static void dump_sets (pfarg_setdesc_t *set, int num_sets)
 
static void dump_setinfo (pfarg_setinfo_t *setinfo, int num_sets)
 
static void dump_pmc (pfm_control_state_t *ctl)
 
static void dump_pmd (pfm_control_state_t *ctl)
 
static void dump_smpl_hdr (pfm_dfl_smpl_hdr_t *hdr)
 
static void dump_smpl (pfm_dfl_smpl_entry_t *entry)
 
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 (hwd_control_state_t *ctl0)
 
int tune_up_fd (int ctx_fd)
 
static int attach (hwd_control_state_t *ctl, unsigned long tid)
 
static int detach (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
static int set_domain (hwd_control_state_t *ctl0, int domain)
 
static int set_granularity (hwd_control_state_t *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 (hwd_context_t *thr_ctx)
 
int _papi_pfm_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
 
int _papi_pfm_write (hwd_context_t *ctx, hwd_control_state_t *ctl, long long *from)
 
int _papi_pfm_read (hwd_context_t *ctx0, hwd_control_state_t *ctl0, long long **events, int flags)
 
int _papi_pfm_start (hwd_context_t *ctx0, hwd_control_state_t *ctl0)
 
int _papi_pfm_stop (hwd_context_t *ctx0, hwd_control_state_t *ctl0)
 
static int round_requested_ns (int ns)
 
int _papi_pfm_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
 
int _papi_pfm_shutdown (hwd_context_t *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, vptr_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, hwd_siginfo_t *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 (hwd_control_state_t *ctl0)
 
static int _papi_pfm_allocate_registers (EventSetInfo_t *ESI)
 
static int _papi_pfm_update_control_state (hwd_control_state_t *ctl0, NativeInfo_t *native, int count, hwd_context_t *ctx0)
 

Variables

papi_vector_t _perfmon2_vector
 
static int _perfmon2_pfm_pmu_type = -1
 
static pfmlib_regmask_t _perfmon2_pfm_unavailable_pmcs
 
static pfmlib_regmask_t _perfmon2_pfm_unavailable_pmds
 

Macro Definition Documentation

◆ BPL

#define BPL   (sizeof(uint64_t)<<3)

Definition at line 1398 of file perfmon2/perfmon.c.

◆ LBPL

#define LBPL   6

Definition at line 1399 of file perfmon2/perfmon.c.

◆ PFM_MAX_PMCDS

#define PFM_MAX_PMCDS   20

Definition at line 188 of file perfmon2/perfmon.c.

Typedef Documentation

◆ uint

typedef unsigned uint

Definition at line 40 of file perfmon2/perfmon.c.

Function Documentation

◆ _papi_pfm_allocate_registers()

static int _papi_pfm_allocate_registers ( EventSetInfo_t ESI)
static

Definition at line 2117 of file perfmon2/perfmon.c.

2118{
2119 int i, j;
2120 for ( i = 0; i < ESI->NativeCount; i++ ) {
2122 ( ESI->NativeInfoArray[i].ni_event,
2123 ESI->NativeInfoArray[i].ni_bits ) != PAPI_OK )
2124 goto bail;
2125 }
2126 return PAPI_OK;
2127 bail:
2128 for ( j = 0; j < i; j++ )
2129 memset( ESI->NativeInfoArray[j].ni_bits, 0x0,
2130 sizeof ( pfm_register_t ) );
2131 return PAPI_ECNFLCT;
2132}
int i
#define PAPI_OK
Definition: f90papi.h:73
#define PAPI_ECNFLCT
Definition: f90papi.h:234
int _papi_libpfm_ntv_code_to_bits(unsigned int EventCode, hwd_register_t *bits)
NativeInfo_t * NativeInfoArray
hwd_register_t * ni_bits
Here is the call graph for this function:

◆ _papi_pfm_ctl()

int _papi_pfm_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)

Definition at line 1199 of file perfmon2/perfmon.c.

1200{
1201 switch ( code ) {
1202 case PAPI_MULTIPLEX:
1203 {
1204 option->multiplex.ns = round_requested_ns( option->multiplex.ns );
1205 ( ( pfm_control_state_t * ) ( option->multiplex.ESI->ctl_state ) )->
1206 multiplexed = option->multiplex.ns;
1207 return ( PAPI_OK );
1208 }
1209
1210 case PAPI_ATTACH:
1211 return ( attach
1212 ( ( pfm_control_state_t * ) ( option->attach.ESI->ctl_state ),
1213 option->attach.tid ) );
1214 case PAPI_DETACH:
1215 return ( detach
1216 ( ctx,
1217 ( pfm_control_state_t * ) ( option->attach.ESI->
1218 ctl_state ) ) );
1219
1220 case PAPI_DOMAIN:
1221 return ( set_domain
1222 ( ( pfm_control_state_t * ) ( option->domain.ESI->ctl_state ),
1223 option->domain.domain ) );
1224 case PAPI_GRANUL:
1225 return ( set_granularity
1226 ( ( pfm_control_state_t * ) ( option->granularity.ESI->
1227 ctl_state ),
1228 option->granularity.granularity ) );
1229#if 0
1230 case PAPI_DATA_ADDRESS:
1231 ret =
1232 set_default_domain( ( pfm_control_state_t * ) ( option->
1233 address_range.ESI->
1234 ctl_state ),
1235 option->address_range.domain );
1236 if ( ret != PAPI_OK )
1237 return ( ret );
1238 set_drange( ctx,
1239 ( pfm_control_state_t * ) ( option->address_range.ESI->
1240 ctl_state ), option );
1241 return ( PAPI_OK );
1242 case PAPI_INSTR_ADDRESS:
1243 ret =
1244 set_default_domain( ( pfm_control_state_t * ) ( option->
1245 address_range.ESI->
1246 ctl_state ),
1247 option->address_range.domain );
1248 if ( ret != PAPI_OK )
1249 return ( ret );
1250 set_irange( ctx,
1251 ( pfm_control_state_t * ) ( option->address_range.ESI->
1252 ctl_state ), option );
1253 return ( PAPI_OK );
1254#endif
1255
1256
1257 case PAPI_DEF_ITIMER:
1258 {
1259 /* flags are currently ignored, eventually the flags will be able
1260 to specify whether or not we use POSIX itimers (clock_gettimer) */
1261 if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
1262 ( option->itimer.itimer_sig != SIGALRM ) )
1263 return PAPI_EINVAL;
1264 if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
1265 ( option->itimer.itimer_sig != SIGVTALRM ) )
1266 return PAPI_EINVAL;
1267 if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
1268 ( option->itimer.itimer_sig != SIGPROF ) )
1269 return PAPI_EINVAL;
1270 if ( option->itimer.ns > 0 )
1271 option->itimer.ns = round_requested_ns( option->itimer.ns );
1272 /* At this point, we assume the user knows what he or
1273 she is doing, they maybe doing something arch specific */
1274 return PAPI_OK;
1275 }
1276
1277 case PAPI_DEF_MPX_NS:
1278 {
1279 option->multiplex.ns = round_requested_ns( option->multiplex.ns );
1280 return ( PAPI_OK );
1281 }
1282 case PAPI_DEF_ITIMER_NS:
1283 {
1284 option->itimer.ns = round_requested_ns( option->itimer.ns );
1285 return ( PAPI_OK );
1286 }
1287 default:
1288 return ( PAPI_ENOSUPP );
1289 }
1290}
static int set_default_domain(EventSetInfo_t *zero, int domain)
Definition: aix.c:510
#define PAPI_INSTR_ADDRESS
Definition: f90papi.h:209
#define PAPI_GRANUL
Definition: f90papi.h:179
#define PAPI_DETACH
Definition: f90papi.h:64
#define PAPI_ATTACH
Definition: f90papi.h:70
#define PAPI_EINVAL
Definition: f90papi.h:115
#define PAPI_ENOSUPP
Definition: f90papi.h:244
#define PAPI_DOMAIN
Definition: f90papi.h:159
#define PAPI_DEF_MPX_NS
Definition: f90papi.h:235
#define PAPI_DATA_ADDRESS
Definition: f90papi.h:89
#define PAPI_MULTIPLEX
Definition: f90papi.h:223
#define PAPI_DEF_ITIMER
Definition: papi.h:462
#define PAPI_DEF_ITIMER_NS
Definition: papi.h:463
static int set_irange(hwd_context_t *ctx, hwd_control_state_t *current_state, _papi_int_option_t *option)
Definition: perfmon-ia64.c:919
static int set_drange(hwd_context_t *ctx, hwd_control_state_t *current_state, _papi_int_option_t *option)
Definition: perfmon-ia64.c:767
static int attach(hwd_control_state_t *ctl, unsigned long tid)
static int set_granularity(hwd_control_state_t *this_state, int domain)
static int round_requested_ns(int ns)
static int set_domain(hwd_control_state_t *ctl0, int domain)
static int detach(hwd_context_t *ctx, hwd_control_state_t *ctl)
hwd_control_state_t * ctl_state
EventSetInfo_t * ESI
EventSetInfo_t * ESI
unsigned long tid
EventSetInfo_t * ESI
EventSetInfo_t * ESI
EventSetInfo_t * ESI
_papi_int_domain_t domain
_papi_int_multiplex_t multiplex
_papi_int_granularity_t granularity
_papi_int_attach_t attach
_papi_int_itimer_t itimer
_papi_int_addr_range_t address_range
Here is the call graph for this function:

◆ _papi_pfm_dispatch_timer()

static void _papi_pfm_dispatch_timer ( int  n,
hwd_siginfo_t info,
void *  uc 
)
static

Definition at line 1739 of file perfmon2/perfmon.c.

1740{
1742#ifdef HAVE_PFM_MSG_TYPE
1743 pfm_msg_t msg;
1744#else
1745 pfarg_msg_t msg;
1746#endif
1747 int ret, wanted_fd, fd = info->si_fd;
1748 vptr_t address;
1751
1752 if ( thread == NULL ) {
1753 PAPIERROR( "thread == NULL in _papi_pfm_dispatch_timer!" );
1755 ret = read( fd, &msg, sizeof ( msg ) );
1756 pfm_restart( fd );
1757 }
1758 return;
1759 }
1760
1761 if ( thread->running_eventset[cidx] == NULL ) {
1762 PAPIERROR
1763 ( "thread->running_eventset == NULL in _papi_pfm_dispatch_timer!" );
1765 ret = read( fd, &msg, sizeof ( msg ) );
1766 pfm_restart( fd );
1767 }
1768 return;
1769 }
1770
1771 if ( thread->running_eventset[cidx]->overflow.flags == 0 ) {
1772 PAPIERROR
1773 ( "thread->running_eventset->overflow.flags == 0 in _papi_pfm_dispatch_timer!" );
1775 ret = read( fd, &msg, sizeof ( msg ) );
1776 pfm_restart( fd );
1777 }
1778 return;
1779 }
1780
1781 ctx.si = info;
1782 ctx.ucontext = ( hwd_ucontext_t * ) uc;
1783
1784 if ( thread->running_eventset[cidx]->overflow.
1785 flags & PAPI_OVERFLOW_FORCE_SW ) {
1786 address = GET_OVERFLOW_ADDRESS( ctx );
1787 _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL,
1788 0, 0, &thread, cidx );
1789 } else {
1790 if ( thread->running_eventset[cidx]->overflow.flags ==
1792 wanted_fd =
1793 ( ( pfm_control_state_t * ) ( thread->running_eventset[cidx]->
1794 ctl_state ) )->ctx_fd;
1795 } else {
1796 wanted_fd = ( ( pfm_context_t * ) thread->context[cidx] )->ctx_fd;
1797 }
1798 if ( wanted_fd != fd ) {
1799 SUBDBG( "expected fd %d, got %d in _papi_hwi_dispatch_timer!",
1800 wanted_fd, fd );
1802 ret = read( fd, &msg, sizeof ( msg ) );
1803 pfm_restart( fd );
1804 }
1805 return;
1806 }
1807 retry:
1808 ret = read( fd, &msg, sizeof ( msg ) );
1809 if ( ret == -1 ) {
1810 if ( errno == EINTR ) {
1811 SUBDBG( "read(%d) interrupted, retrying\n", fd );
1812 goto retry;
1813 } else {
1814 PAPIERROR( "read(%d): errno %d", fd, errno );
1815 }
1816 } else if ( ret != sizeof ( msg ) ) {
1817 PAPIERROR( "read(%d): short %d vs. %d bytes", fd, ret,
1818 sizeof ( msg ) );
1819 ret = -1;
1820 }
1821
1822 if ( msg.type != PFM_MSG_OVFL ) {
1823 PAPIERROR( "unexpected msg type %d", msg.type );
1824 ret = -1;
1825 }
1826#if 0
1827 if ( msg.pfm_ovfl_msg.msg_ovfl_tid != mygettid( ) ) {
1828 PAPIERROR( "unmatched thread id %lx vs. %lx",
1829 msg.pfm_ovfl_msg.msg_ovfl_tid, mygettid( ) );
1830 ret = -1;
1831 }
1832#endif
1833
1834 if ( ret != -1 ) {
1835 if ( ( thread->running_eventset[cidx]->state & PAPI_PROFILING ) &&
1836 !( thread->running_eventset[cidx]->profile.
1837 flags & PAPI_PROFIL_FORCE_SW ) )
1838 process_smpl_buf( 0, sizeof ( pfm_dfl_smpl_entry_t ), &thread );
1839 else {
1840 /* PAPI assumes that the overflow vector contains the register index of the
1841 overflowing native event. That is generally true, but Stephane used some
1842 tricks to offset the fixed counters on Core2 (Core? i7?) by 16. This hack
1843 corrects for that hack in a (hopefully) transparent manner */
1844 unsigned long i, vector = msg.pfm_ovfl_msg.msg_ovfl_pmds[0];
1845 pfm_control_state_t *ctl =
1846 ( pfm_control_state_t * ) thread->running_eventset[cidx]->
1847 ctl_state;
1848 for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
1849 /* We're only comparing to pmds[0]. A more robust implementation would
1850 compare to pmds[0-3]. The bit mask must be converted to an index
1851 for the comparison to work */
1852 if ( ctl->pd[i].reg_num ==
1853 ffsl( msg.pfm_ovfl_msg.msg_ovfl_pmds[0] ) - 1 ) {
1854 /* if a match is found, convert the index back to a bitmask */
1855 vector = 1 << i;
1856 break;
1857 }
1858 }
1859 _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx,
1860 ( vptr_t ) ( ( size_t )
1861 msg.
1862 pfm_ovfl_msg.
1863 msg_ovfl_ip ),
1864 NULL, vector, 0, &thread,
1865 cidx );
1866 }
1867 }
1868
1869 if ( ( ret = pfm_restart( fd ) ) ) {
1870 PAPIERROR( "pfm_restart(%d): %s", fd, strerror( ret ) );
1871 }
1872 }
1873}
#define GET_OVERFLOW_ADDRESS(ctx)
Definition: aix-context.h:12
int errno
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:229
static pid_t mygettid(void)
Definition: darwin-common.h:11
int _papi_hwi_dispatch_overflow_signal(void *papiContext, vptr_t address, int *isHardware, long long overflow_bit, int genOverflowBit, ThreadInfo_t **t, int cidx)
Definition: extras.c:216
#define PAPI_PROFILING
Definition: f90papi.h:150
#define PAPI_OVERFLOW_FORCE_SW
Definition: f90papi.h:131
#define PAPI_OVERFLOW_HARDWARE
Definition: f90papi.h:157
#define PAPI_PROFIL_FORCE_SW
Definition: f90papi.h:257
void * thread(void *arg)
Definition: kufrin.c:38
void * vptr_t
Definition: papi.h:576
#define SUBDBG(format, args...)
Definition: papi_debug.h:64
void PAPIERROR(char *format,...)
static int cidx
papi_vector_t _perfmon2_vector
static int process_smpl_buf(int num_smpl_pmds, int entry_size, ThreadInfo_t **thr)
os_err_t pfm_restart(int fd)
hwd_siginfo_t * si
hwd_ucontext_t * ucontext
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
uint16_t reg_num
Definition: perfmon_v2.h:39
pfarg_pmd_t pd[PFMLIB_MAX_PMDS]
unsigned long msg_ovfl_pmds[4]
unsigned int pfp_event_count
Definition: pfmlib.h:109
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
Definition: threads.h:97
pfm_ovfl_msg_t pfm_ovfl_msg
Here is the call graph for this function:

◆ _papi_pfm_init_component()

int _papi_pfm_init_component ( int  cidx)

Definition at line 750 of file perfmon2/perfmon.c.

751{
752 int retval;
754
755 /* The following checks the PFMLIB version
756 against the perfmon2 kernel version... */
759
760 retval = get_string_from_file( "/sys/kernel/perfmon/version",
763 if ( retval != PAPI_OK ) {
765 "/sys/kernel/perfmon/version not found",PAPI_MAX_STR_LEN);
766 goto fn_fail;
767 }
768
769#ifdef PFM_VERSION
770 sprintf( buf, "%d.%d", PFM_VERSION_MAJOR( PFM_VERSION ),
771 PFM_VERSION_MINOR( PFM_VERSION ) );
772 SUBDBG( "Perfmon2 library versions...kernel: %s library: %s\n",
774 if ( strcmp( _perfmon2_vector.cmp_info.kernel_version, buf ) != 0 ) {
775 /* do a little exception processing; 81 is compatible with 80 */
776 if ( !( ( PFM_VERSION_MINOR( PFM_VERSION ) == 81 ) &&
777 ( strncmp( _perfmon2_vector.cmp_info.kernel_version, "2.8", 3 ) ==
778 0 ) ) ) {
779 PAPIERROR( "Version mismatch of libpfm: compiled %s "
780 "vs. installed %s\n",
783 goto fn_fail;
784 }
785 }
786#endif
787
789
790
791 /* Run the libpfm-specific setup */
793 if (retval) goto fn_fail;
794
795 /* Load the module, find out if any PMC's/PMD's are off limits */
796
797 /* Perfmon2 timeouts are based on the clock tick, we need to check
798 them otherwise it will complain at us when we multiplex */
799
800 unsigned long min_timeout_ns;
801
802 struct timespec ts;
803
804 if ( syscall( __NR_clock_getres, CLOCK_REALTIME, &ts ) == -1 ) {
805 PAPIERROR( "Could not detect proper HZ rate, multiplexing may fail\n" );
806 min_timeout_ns = 10000000;
807 } else {
808 min_timeout_ns = ts.tv_nsec;
809 }
810
811 /* This will fail if we've done timeout detection wrong */
814 &min_timeout_ns );
815 if ( retval != PAPI_OK ) {
816 goto fn_fail;
817 }
818
820 /* powerpc */
823 if (strcmp(_papi_hwi_system_info.hw_info.model_string, "POWER6" ) == 0) {
827 }
828 } else {
830 }
831
833 switch ( _perfmon2_pfm_pmu_type ) {
834#ifdef PFMLIB_SPARC_ULTRA12_PMU
840 break;
841#endif
842 default:
845 break;
846 }
847 }
848
851 }
852
858 }
859
860 fn_exit:
861 _papi_hwd[cidx]->cmp_info.disabled = retval;
862 return retval;
863 fn_fail:
864 goto fn_exit;
865}
struct papi_vectors * _papi_hwd[]
volatile int buf[CACHE_FLUSH_BUFFER_SIZE_INTS]
Definition: do_loops.c:12
#define PAPI_DOM_USER
Definition: f90papi.h:174
#define PAPI_DOM_OTHER
Definition: f90papi.h:21
#define PAPI_VENDOR_IBM
Definition: f90papi.h:61
#define PAPI_VENDOR_CRAY
Definition: f90papi.h:211
#define PAPI_DOM_KERNEL
Definition: f90papi.h:254
#define PAPI_VENDOR_SUN
Definition: f90papi.h:65
#define PAPI_DOM_SUPERVISOR
Definition: f90papi.h:109
#define PAPI_VENDOR_INTEL
Definition: f90papi.h:275
#define PAPI_VENDOR_AMD
Definition: f90papi.h:230
#define PAPI_MAX_STR_LEN
Definition: f90papi.h:77
#define PAPI_ESYS
Definition: f90papi.h:136
#define PAPI_HUGE_STR_LEN
Definition: f90papi.h:120
#define PFM_VERSION_MAJOR(x)
#define PFM_VERSION_MINOR(x)
int _papi_libpfm_init(papi_vector_t *my_vector, int cidx)
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:56
static pfmlib_regmask_t _perfmon2_pfm_unavailable_pmcs
static int detect_timeout_and_unavail_pmu_regs(pfmlib_regmask_t *r_pmcs, pfmlib_regmask_t *r_pmds, unsigned long *timeout_ns)
static int _perfmon2_pfm_pmu_type
static int get_string_from_file(char *file, char *str, int len)
static pfmlib_regmask_t _perfmon2_pfm_unavailable_pmds
#define PFMLIB_SPARC_ULTRA3I_PMU
Definition: pfmlib.h:274
#define PFMLIB_SPARC_ULTRA12_PMU
Definition: pfmlib.h:272
#define PFMLIB_SPARC_ULTRA3PLUS_PMU
Definition: pfmlib.h:275
#define PFMLIB_SPARC_ULTRA3_PMU
Definition: pfmlib.h:273
#define PFMLIB_SPARC_ULTRA4PLUS_PMU
Definition: pfmlib.h:276
unsigned int cntr_umasks
Definition: papi.h:660
unsigned int fast_counter_read
Definition: papi.h:655
char support_version[PAPI_MIN_STR_LEN]
Definition: papi.h:632
char kernel_version[PAPI_MIN_STR_LEN]
Definition: papi.h:633
char disabled_reason[PAPI_HUGE_STR_LEN]
Definition: papi.h:634
unsigned int fast_real_timer
Definition: papi.h:656
int vendor
Definition: papi.h:781
char model_string[PAPI_MAX_STR_LEN]
Definition: papi.h:784
PAPI_hw_info_t hw_info
int retval
Definition: zero_fork.c:53
Here is the call graph for this function:

◆ _papi_pfm_init_control_state()

static int _papi_pfm_init_control_state ( hwd_control_state_t ctl0)
static

Definition at line 2092 of file perfmon2/perfmon.c.

2093{
2094 pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
2095 pfmlib_input_param_t *inp = &ctl->in;
2096 pfmlib_output_param_t *outp = &ctl->out;
2097 pfarg_pmd_t *pd = ctl->pd;
2098 pfarg_pmc_t *pc = ctl->pc;
2099 pfarg_setdesc_t *set = ctl->set;
2100 pfarg_setinfo_t *setinfo = ctl->setinfo;
2101
2102 memset( inp, 0, sizeof ( *inp ) );
2103 memset( outp, 0, sizeof ( *inp ) );
2104 memset( pc, 0, sizeof ( ctl->pc ) );
2105 memset( pd, 0, sizeof ( ctl->pd ) );
2106 memset( set, 0, sizeof ( ctl->set ) );
2107 memset( setinfo, 0, sizeof ( ctl->setinfo ) );
2108 /* Will be filled by update now...until this gets another arg */
2109 ctl->ctx = NULL;
2110 ctl->ctx_fd = -1;
2111 ctl->load = NULL;
2113 return ( PAPI_OK );
2114}
pfarg_setdesc_t set[PFMLIB_MAX_PMDS]
pfarg_setinfo_t setinfo[PFMLIB_MAX_PMDS]
pfarg_pmc_t pc[PFMLIB_MAX_PMCS]
Here is the call graph for this function:

◆ _papi_pfm_init_thread()

static int _papi_pfm_init_thread ( hwd_context_t thr_ctx)
static

Definition at line 874 of file perfmon2/perfmon.c.

875{
876 pfarg_load_t load_args;
877 pfarg_ctx_t newctx;
878 int ret, ctx_fd;
879
880#if defined(USE_PROC_PTTIMER)
881 ret = init_proc_thread_timer( thr_ctx );
882 if ( ret != PAPI_OK )
883 return ( ret );
884#endif
885
886 memset( &newctx, 0, sizeof ( newctx ) );
887 memset( &load_args, 0, sizeof ( load_args ) );
888
889 if ( ( ret = pfm_create_context( &newctx, NULL, NULL, 0 ) ) == -1 ) {
890 PAPIERROR( "pfm_create_context(): %s",
891 strerror( errno ) );
892 return ( PAPI_ESYS );
893 }
894 SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", ret );
895 tune_up_fd( ret );
896 ctx_fd = ret;
897
898 memcpy( &( ( pfm_context_t * ) thr_ctx )->ctx, &newctx, sizeof ( newctx ) );
899 ( ( pfm_context_t * ) thr_ctx )->ctx_fd = ctx_fd;
900 load_args.load_pid = mygettid( );
901 memcpy( &( ( pfm_context_t * ) thr_ctx )->load, &load_args,
902 sizeof ( load_args ) );
903
904 return ( PAPI_OK );
905}
int init_proc_thread_timer(hwd_context_t *thr_ctx)
int tune_up_fd(int ctx_fd)
os_err_t pfm_create_context(pfarg_ctx_t *ctx, char *smpl_name, void *smpl_arg, size_t smpl_size)
uint32_t load_pid
Definition: perfmon_v2.h:69
Here is the call graph for this function:

◆ _papi_pfm_read()

int _papi_pfm_read ( hwd_context_t ctx0,
hwd_control_state_t ctl0,
long long **  events,
int  flags 
)

Definition at line 965 of file perfmon2/perfmon.c.

967{
968 ( void ) flags; /*unused */
969 unsigned int i;
970 int ret;
971 long long tot_runs = 0LL;
973 pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
974
975 ret = _papi_pfm_read_pmds( ctx, ctl );
976 if ( ret != PAPI_OK )
977 return PAPI_ESYS;
978
979 /* Copy the values over */
980
981 for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
982 if ( ctl->pd[i].reg_flags & PFM_REGFL_OVFL_NOTIFY )
983 ctl->counts[i] = ctl->pd[i].reg_value - ctl->pd[i].reg_long_reset;
984 else
985 ctl->counts[i] = ctl->pd[i].reg_value;
986 SUBDBG( "PMD[%d] = %lld (LLD),%llu (LLU)\n", i,
987 ( unsigned long long ) ctl->counts[i],
988 ( unsigned long long ) ctl->pd[i].reg_value );
989 }
990 *events = ctl->counts;
991
992 /* If we're not multiplexing, bail now */
993
994 if ( ctl->num_sets == 1 )
995 return ( PAPI_OK );
996
997 /* If we're multiplexing, get the scaling information */
998
999 SUBDBG( "PFM_GETINFO_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, ctl->setinfo,
1000 ctl->num_sets );
1001 if ( ( ret =
1002 pfm_getinfo_evtsets( ctl->ctx_fd, ctl->setinfo, ctl->num_sets ) ) ) {
1004 dump_setinfo( ctl->setinfo, ctl->num_sets ) );
1005 PAPIERROR( "pfm_getinfo_evtsets(%d,%p,%d): %s", ctl->ctx_fd,
1006 ctl->setinfo, ctl->num_sets, strerror( ret ) );
1007 *events = NULL;
1008 return ( PAPI_ESYS );
1009 }
1011
1012 /* Add up the number of total runs */
1013
1014 for ( i = 0; i < ( unsigned int ) ctl->num_sets; i++ )
1015 tot_runs += ctl->setinfo[i].set_runs;
1016
1017 /* Now scale the values */
1018
1019 for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
1020 SUBDBG
1021 ( "Counter %d is in set %d ran %llu of %llu times, old count %lld.\n",
1022 i, ctl->pd[i].reg_set,
1023 ( unsigned long long ) ctl->setinfo[ctl->pd[i].reg_set].set_runs,
1024 ( unsigned long long ) tot_runs, ctl->counts[i] );
1025 if ( ctl->setinfo[ctl->pd[i].reg_set].set_runs )
1026 ctl->counts[i] =
1027 ( ctl->counts[i] * tot_runs ) /
1028 ctl->setinfo[ctl->pd[i].reg_set].set_runs;
1029 else {
1030 ctl->counts[i] = 0;
1031 SUBDBG( "Set %lld didn't run!!!!\n",
1032 ( unsigned long long ) ctl->pd[i].reg_set );
1033 }
1034 SUBDBG( "Counter %d, new count %lld.\n", i, ctl->counts[i] );
1035 }
1036
1037 return PAPI_OK;
1038}
#define DEBUGCALL(a, b)
char events[MAX_EVENTS][BUFSIZ]
#define PFM_REGFL_OVFL_NOTIFY
#define DEBUG_SUBSTRATE
Definition: papi_debug.h:27
int _papi_pfm_read_pmds(pfm_context_t *ctx, pfm_control_state_t *ctl)
static void dump_setinfo(pfarg_setinfo_t *setinfo, int num_sets)
os_err_t pfm_getinfo_evtsets(int fd, pfarg_setinfo_t *info, int count)
int
Definition: sde_internal.h:89
uint64_t reg_value
Definition: perfmon_v2.h:42
uint32_t reg_flags
Definition: perfmon_v2.h:41
uint16_t reg_set
Definition: perfmon_v2.h:40
uint64_t reg_long_reset
Definition: perfmon_v2.h:43
uint64_t set_runs
Definition: perfmon_v2.h:89
long long counts[PFMLIB_MAX_PMDS]
Here is the call graph for this function:

◆ _papi_pfm_read_pmds()

int _papi_pfm_read_pmds ( pfm_context_t ctx,
pfm_control_state_t ctl 
)

Definition at line 266 of file perfmon2/perfmon.c.

267{
268 ( void ) ctx; /*unused */
269 unsigned int i = 0;
270 int ret;
271
272 SUBDBG( "PFM_READ_PMDS(%d,%p,%d)\n", ctl->ctx_fd, ctl->pd,
273 ctl->in.pfp_event_count );
274 if ( ctl->in.pfp_event_count > PFM_MAX_PMCDS ) {
275 for ( i = 0; i < ctl->in.pfp_event_count - PFM_MAX_PMCDS;
276 i += PFM_MAX_PMCDS ) {
277 if ( ( ret =
278 pfm_read_pmds( ctl->ctx_fd, ctl->pd + i,
279 PFM_MAX_PMCDS ) ) ) {
281 PAPIERROR( "pfm_read_pmds(%d,%p,%d): %s", ctl->ctx_fd, ctl->pd,
282 ctl->in.pfp_event_count, strerror( ret ) );
283 return ( ( errno == EBADF ) ? PAPI_ECLOST : PAPI_ESYS );
284 }
285 }
287 }
288 if ( ( ret =
289 pfm_read_pmds( ctl->ctx_fd, ctl->pd + i,
290 ctl->in.pfp_event_count - i ) ) ) {
292 PAPIERROR( "pfm_read_pmds(%d,%p,%d): %s", ctl->ctx_fd, ctl->pd,
293 ctl->in.pfp_event_count, strerror( ret ) );
294 return ( ( errno == EBADF ) ? PAPI_ECLOST : PAPI_ESYS );
295 }
297
298 return PAPI_OK;
299}
#define PAPI_ECLOST
Definition: f90papi.h:141
static void dump_pmd(pfm_control_state_t *ctl)
#define PFM_MAX_PMCDS
os_err_t pfm_read_pmds(int fd, pfarg_pmd_t *pmds, int count)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _papi_pfm_reset()

int _papi_pfm_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 909 of file perfmon2/perfmon.c.

910{
911 unsigned int i;
912 int ret;
913
914 /* Read could have clobbered the values */
915 for ( i = 0; i < ( ( pfm_control_state_t * ) ctl )->in.pfp_event_count;
916 i++ ) {
917 if ( ( ( pfm_control_state_t * ) ctl )->pd[i].
918 reg_flags & PFM_REGFL_OVFL_NOTIFY )
919 ( ( pfm_control_state_t * ) ctl )->pd[i].reg_value =
920 ( ( pfm_control_state_t * ) ctl )->pd[i].reg_long_reset;
921 else
922 ( ( pfm_control_state_t * ) ctl )->pd[i].reg_value = 0ULL;
923 }
924
925 ret =
927 ( pfm_control_state_t * ) ctl );
928 if ( ret != PAPI_OK )
929 return PAPI_ESYS;
930
931 return ( PAPI_OK );
932}
int _papi_pfm_write_pmds(pfm_context_t *ctx, pfm_control_state_t *ctl)
Here is the call graph for this function:

◆ _papi_pfm_set_overflow()

static int _papi_pfm_set_overflow ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
)
static

Definition at line 2010 of file perfmon2/perfmon.c.

2011{
2012 pfm_control_state_t *this_state =
2013 ( pfm_control_state_t * ) ( ESI->ctl_state );
2014 int j, retval = PAPI_OK, *pos;
2015
2016 /* Which counter are we on, this looks suspicious because of the pos[0],
2017 but this could be because of derived events. We should do more here
2018 to figure out exactly what the position is, because the event may
2019 actually have more than one position. */
2020
2021 pos = ESI->EventInfoArray[EventIndex].pos;
2022 j = pos[0];
2023 SUBDBG( "Hardware counter %d used in overflow, threshold %d\n", j,
2024 threshold );
2025
2026 if ( threshold == 0 ) {
2027 /* If this counter isn't set to overflow */
2028
2029 if ( ( this_state->pd[j].reg_flags & PFM_REGFL_OVFL_NOTIFY ) == 0 )
2030 return ( PAPI_EINVAL );
2031
2032 /* Remove the signal handler */
2033
2035 if ( retval != PAPI_OK )
2036 return ( retval );
2037
2038 /* Disable overflow */
2039
2040 this_state->pd[j].reg_flags ^= PFM_REGFL_OVFL_NOTIFY;
2041
2042 /*
2043 * we may want to reset the other PMDs on
2044 * every overflow. If we do not set
2045 * this, the non-overflowed counters
2046 * will be untouched.
2047
2048 if (inp.pfp_event_count > 1)
2049 this_state->pd[j].reg_reset_pmds[0] ^= 1UL << counter_to_reset */
2050
2051 /* Clear the overflow period */
2052
2053 this_state->pd[j].reg_value = 0;
2054 this_state->pd[j].reg_long_reset = 0;
2055 this_state->pd[j].reg_short_reset = 0;
2056 this_state->pd[j].reg_random_seed = 0;
2057 this_state->pd[j].reg_random_mask = 0;
2058 } else {
2059 /* Enable the signal handler */
2060
2061 retval =
2064 if ( retval != PAPI_OK )
2065 return ( retval );
2066
2067 /* Set it to overflow */
2068
2069 this_state->pd[j].reg_flags |= PFM_REGFL_OVFL_NOTIFY;
2070
2071 /*
2072 * we may want to reset the other PMDs on
2073 * every overflow. If we do not set
2074 * this, the non-overflowed counters
2075 * will be untouched.
2076
2077 if (inp.pfp_event_count > 1)
2078 this_state->pd[j].reg_reset_pmds[0] |= 1UL << counter_to_reset */
2079
2080 /* Set the overflow period */
2081
2082 this_state->pd[j].reg_value = -( unsigned long long ) threshold + 1;
2083 this_state->pd[j].reg_short_reset =
2084 -( unsigned long long ) threshold + 1;
2085 this_state->pd[j].reg_long_reset =
2086 -( unsigned long long ) threshold + 1;
2087 }
2088 return ( retval );
2089}
int _papi_hwi_start_signal(int signal, int need_context, int cidx)
Definition: extras.c:403
int _papi_hwi_stop_signal(int signal)
Definition: extras.c:443
static int threshold
long long int long long
Definition: sde_internal.h:85
int pos[PAPI_EVENTS_IN_DERIVED_EVENT]
EventInfo_t * EventInfoArray
uint64_t reg_short_reset
Definition: perfmon_v2.h:44
uint64_t reg_random_mask
Definition: perfmon_v2.h:50
uint32_t reg_random_seed
Definition: perfmon_v2.h:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _papi_pfm_set_profile()

static int _papi_pfm_set_profile ( EventSetInfo_t ESI,
int  EventIndex,
int  threshold 
)
static

Definition at line 1884 of file perfmon2/perfmon.c.

1885{
1888 pfm_context_t *ctx = ( pfm_context_t * ) ( ESI->master->context[cidx] );
1889 pfarg_ctx_t newctx;
1890 void *buf_addr = NULL;
1891 pfm_dfl_smpl_arg_t buf_arg;
1892 pfm_dfl_smpl_hdr_t *hdr;
1893 int i, ret, ctx_fd;
1894
1895 memset( &newctx, 0, sizeof ( newctx ) );
1896
1897 if ( threshold == 0 ) {
1898 SUBDBG( "MUNMAP(%p,%lld)\n", ctx->smpl_buf,
1899 ( unsigned long long ) ctx->smpl.buf_size );
1900 munmap( ctx->smpl_buf, ctx->smpl.buf_size );
1901
1902 i = close( ctl->ctx_fd );
1903 SUBDBG( "CLOSE fd %d returned %d\n", ctl->ctx_fd, i );
1904 (void) i;
1905
1906 /* Thread has master context */
1907
1908 ctl->ctx_fd = ctx->ctx_fd;
1909 ctl->ctx = &ctx->ctx;
1910 memset( &ctx->smpl, 0, sizeof ( buf_arg ) );
1911 ctx->smpl_buf = NULL;
1912 ret = _papi_pfm_set_overflow( ESI, EventIndex, threshold );
1913//#warning "This should be handled somewhere else"
1914 ESI->state &= ~( PAPI_OVERFLOWING );
1916
1917 return ( ret );
1918 }
1919
1920 memset( &buf_arg, 0, sizeof ( buf_arg ) );
1921 buf_arg.buf_size = 2 * getpagesize( );
1922
1923 SUBDBG( "PFM_CREATE_CONTEXT(%p,%s,%p,%d)\n", &newctx, PFM_DFL_SMPL_NAME,
1924 &buf_arg, ( int ) sizeof ( buf_arg ) );
1925 if ( ( ret =
1926 pfm_create_context( &newctx, PFM_DFL_SMPL_NAME, &buf_arg,
1927 sizeof ( buf_arg ) ) ) == -1 ) {
1928 DEBUGCALL( DEBUG_SUBSTRATE, dump_smpl_arg( &buf_arg ) );
1929 PAPIERROR( "_papi_hwd_set_profile:pfm_create_context(): %s",
1930 strerror( errno ) );
1931 return ( PAPI_ESYS );
1932 }
1933 ctx_fd = ret;
1934 SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", ctx_fd );
1935 tune_up_fd( ret );
1936
1937 SUBDBG( "MMAP(NULL,%lld,%d,%d,%d,0)\n",
1938 ( unsigned long long ) buf_arg.buf_size, PROT_READ, MAP_PRIVATE,
1939 ctx_fd );
1940 buf_addr =
1941 mmap( NULL, ( size_t ) buf_arg.buf_size, PROT_READ, MAP_PRIVATE, ctx_fd,
1942 0 );
1943 if ( buf_addr == MAP_FAILED ) {
1944 PAPIERROR( "mmap(NULL,%d,%d,%d,%d,0): %s", buf_arg.buf_size, PROT_READ,
1945 MAP_PRIVATE, ctx_fd, strerror( errno ) );
1946 close( ctx_fd );
1947 return ( PAPI_ESYS );
1948 }
1949 SUBDBG( "Sample buffer is located at %p\n", buf_addr );
1950
1951 hdr = ( pfm_dfl_smpl_hdr_t * ) buf_addr;
1952 SUBDBG( "hdr_cur_offs=%llu version=%u.%u\n",
1953 ( unsigned long long ) hdr->hdr_cur_offs,
1956
1957 if ( PFM_VERSION_MAJOR( hdr->hdr_version ) < 1 ) {
1958 PAPIERROR( "invalid buffer format version %d",
1960 munmap( buf_addr, buf_arg.buf_size );
1961 close( ctx_fd );
1962 return PAPI_ESYS;
1963 }
1964
1965 ret = _papi_pfm_set_overflow( ESI, EventIndex, threshold );
1966 if ( ret != PAPI_OK ) {
1967 munmap( buf_addr, buf_arg.buf_size );
1968 close( ctx_fd );
1969 return ( ret );
1970 }
1971
1972 /* Look up the native event code */
1973
1975 pfarg_pmd_t *pd;
1976 int pos, native_index;
1977 pd = ctl->pd;
1978 pos = ESI->EventInfoArray[EventIndex].pos[0];
1979 native_index =
1980 ( ( pfm_register_t * ) ( ESI->NativeInfoArray[pos].ni_bits ) )->
1981 event;
1982 setup_ear_event( native_index, &pd[pos], ESI->profile.flags );
1983 }
1984
1985 if ( ESI->profile.flags & PAPI_PROFIL_RANDOM ) {
1986 pfarg_pmd_t *pd;
1987 int pos;
1988 pd = ctl->pd;
1989 pos = ESI->EventInfoArray[EventIndex].pos[0];
1990 pd[pos].reg_random_seed = 5;
1991 pd[pos].reg_random_mask = 0xff;
1992 }
1993
1994 /* Now close our context it is safe */
1995
1996 // close(ctx->ctx_fd);
1997
1998 /* Copy the new data to the threads context control block */
1999
2000 ctl->ctx_fd = ctx_fd;
2001 memcpy( &ctx->smpl, &buf_arg, sizeof ( buf_arg ) );
2002 ctx->smpl_buf = buf_addr;
2003
2004 return ( PAPI_OK );
2005}
int close(int fd)
Definition: appio.c:179
#define PAPI_PROFIL_INST_EAR
Definition: f90papi.h:206
#define PAPI_OVERFLOWING
Definition: f90papi.h:240
#define PAPI_PROFIL_RANDOM
Definition: f90papi.h:143
#define PAPI_PROFIL_DATA_EAR
Definition: f90papi.h:127
static int setup_ear_event(unsigned int native_index, pfarg_pmd_t *pd, int flags)
static int _papi_pfm_set_overflow(EventSetInfo_t *ESI, int EventIndex, int threshold)
static void dump_smpl_arg(pfm_dfl_smpl_arg_t *arg)
#define PFM_DFL_SMPL_NAME
EventSetProfileInfo_t profile
struct _ThreadInfo * master
EventSetOverflowInfo_t overflow
pfm_dfl_smpl_arg_t smpl
Here is the call graph for this function:

◆ _papi_pfm_shutdown()

int _papi_pfm_shutdown ( hwd_context_t ctx0)

Definition at line 1293 of file perfmon2/perfmon.c.

1294{
1295 pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
1296 int ret;
1297#if defined(USE_PROC_PTTIMER)
1298 close( ctx->stat_fd );
1299#endif
1300
1301
1302 ret = close( ctx->ctx_fd );
1303 SUBDBG( "CLOSE fd %d returned %d\n", ctx->ctx_fd, ret );
1304 (void) ret;
1305
1306 return ( PAPI_OK );
1307}
Here is the call graph for this function:

◆ _papi_pfm_shutdown_component()

int _papi_pfm_shutdown_component ( )

Definition at line 868 of file perfmon2/perfmon.c.

869{
870 return PAPI_OK;
871}

◆ _papi_pfm_start()

int _papi_pfm_start ( hwd_context_t ctx0,
hwd_control_state_t ctl0 
)

Definition at line 1045 of file perfmon2/perfmon.c.

1046{
1047 unsigned int i;
1048 int ret;
1049 pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
1050 pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
1051
1052#if defined(__crayxt)
1053 if ( _papi_hwd_start_create_context ) {
1055
1056 memset( &tmp, 0, sizeof ( tmp ) );
1057 if ( ( ret = pfm_create_context( &tmp, NULL, NULL, 0 ) ) == -1 ) {
1058 PAPIERROR( "_papi_hwd_init:pfm_create_context(): %s",
1059 strerror( errno ) );
1060 return ( PAPI_ESYS );
1061 }
1062 tune_up_fd( ret );
1063 ctl->ctx_fd = ctx->ctx_fd = ret;
1064 }
1065#endif /* XT */
1066
1067 if ( ctl->num_sets > 1 ) {
1068 SUBDBG( "PFM_CREATE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, ctl->set,
1069 ctl->num_sets );
1070 if ( ( ret =
1071 pfm_create_evtsets( ctl->ctx_fd, ctl->set,
1072 ctl->num_sets ) ) != PFMLIB_SUCCESS ) {
1074 PAPIERROR( "pfm_create_evtsets(%d,%p,%d): errno=%d %s",
1075 ctl->ctx_fd, ctl->set, ctl->num_sets, errno,
1076 strerror( ret ) );
1077 perror( "pfm_create_evtsets" );
1078 return ( PAPI_ESYS );
1079 }
1081 }
1082
1083 /*
1084 * Now program the registers
1085 *
1086 * We don't use the same variable to indicate the number of elements passed to
1087 * the kernel because, as we said earlier, pc may contain more elements than
1088 * the number of events (pmd) we specified, i.e., contains more than counting
1089 * monitors.
1090 */
1091
1092 ret = _papi_pfm_write_pmcs( ctx, ctl );
1093 if ( ret != PAPI_OK )
1094 return PAPI_ESYS;
1095
1096 /* Set counters to zero as per PAPI_start man page, unless it is set to overflow */
1097
1098 for ( i = 0; i < ctl->in.pfp_event_count; i++ )
1099 if ( !( ctl->pd[i].reg_flags & PFM_REGFL_OVFL_NOTIFY ) )
1100 ctl->pd[i].reg_value = 0ULL;
1101
1102 /*
1103 * To be read, each PMD must be either written or declared
1104 * as being part of a sample (reg_smpl_pmds)
1105 */
1106
1107 ret = _papi_pfm_write_pmds( ctx, ctl );
1108 if ( ret != PAPI_OK )
1109 return PAPI_ESYS;
1110
1111 SUBDBG( "PFM_LOAD_CONTEXT(%d,%p(%u))\n", ctl->ctx_fd, ctl->load,
1112 ctl->load->load_pid );
1113 if ( ( ret = pfm_load_context( ctl->ctx_fd, ctl->load ) ) ) {
1114 PAPIERROR( "pfm_load_context(%d,%p(%u)): %s", ctl->ctx_fd, ctl->load,
1115 ctl->load->load_pid, strerror( ret ) );
1116 return PAPI_ESYS;
1117 }
1118
1119 SUBDBG( "PFM_START(%d,%p)\n", ctl->ctx_fd, NULL );
1120 if ( ( ret = pfm_start( ctl->ctx_fd, NULL ) ) ) {
1121 PAPIERROR( "pfm_start(%d): %s", ctl->ctx_fd, strerror( ret ) );
1122 return ( PAPI_ESYS );
1123 }
1124 return PAPI_OK;
1125}
double tmp
int _papi_pfm_write_pmcs(pfm_context_t *ctx, pfm_control_state_t *ctl)
static void dump_sets(pfarg_setdesc_t *set, int num_sets)
os_err_t pfm_start(int fd, pfarg_start_t *start)
os_err_t pfm_load_context(int fd, pfarg_load_t *load)
os_err_t pfm_create_evtsets(int fd, pfarg_setdesc_t *setd, int count)
#define PFMLIB_SUCCESS
Definition: pfmlib.h:283
Here is the call graph for this function:

◆ _papi_pfm_stop()

int _papi_pfm_stop ( hwd_context_t ctx0,
hwd_control_state_t ctl0 
)

Definition at line 1128 of file perfmon2/perfmon.c.

1129{
1130 ( void ) ctx0; /*unused */
1131 int ret;
1132 pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
1133// pfm_context_t *ctx = (pfm_context_t *)ctx0;
1134
1135 SUBDBG( "PFM_STOP(%d)\n", ctl->ctx_fd );
1136 if ( ( ret = pfm_stop( ctl->ctx_fd ) ) ) {
1137 /* If this thread is attached to another thread, and that thread
1138 has exited, we can safely discard the error here. */
1139
1140 if ( ( ret == PFMLIB_ERR_NOTSUPP ) &&
1141 ( ctl->load->load_pid != ( unsigned int ) mygettid( ) ) )
1142 return ( PAPI_OK );
1143
1144 PAPIERROR( "pfm_stop(%d): %s", ctl->ctx_fd, strerror( ret ) );
1145 return ( PAPI_ESYS );
1146 }
1147
1148 SUBDBG( "PFM_UNLOAD_CONTEXT(%d) (tid %u)\n", ctl->ctx_fd,
1149 ctl->load->load_pid );
1150 if ( ( ret = pfm_unload_context( ctl->ctx_fd ) ) ) {
1151 PAPIERROR( "pfm_unload_context(%d): %s", ctl->ctx_fd, strerror( ret ) );
1152 return PAPI_ESYS;
1153 }
1154
1155 if ( ctl->num_sets > 1 ) {
1156 static pfarg_setdesc_t set = { 0, 0, 0, 0, {0, 0, 0, 0, 0, 0} };
1157 /* Delete the high sets */
1158 SUBDBG( "PFM_DELETE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, &ctl->set[1],
1159 ctl->num_sets - 1 );
1160 if ( ( ret =
1161 pfm_delete_evtsets( ctl->ctx_fd, &ctl->set[1],
1162 ctl->num_sets - 1 ) ) != PFMLIB_SUCCESS ) {
1164 dump_sets( &ctl->set[1], ctl->num_sets - 1 ) );
1165 PAPIERROR( "pfm_delete_evtsets(%d,%p,%d): %s", ctl->ctx_fd,
1166 &ctl->set[1], ctl->num_sets - 1, strerror( ret ) );
1167 return ( PAPI_ESYS );
1168 }
1170 dump_sets( &ctl->set[1], ctl->num_sets - 1 ) );
1171 /* Reprogram the 0 set */
1172 SUBDBG( "PFM_CREATE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, &set, 1 );
1173 if ( ( ret =
1174 pfm_create_evtsets( ctl->ctx_fd, &set,
1175 1 ) ) != PFMLIB_SUCCESS ) {
1176 DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( &set, 1 ) );
1177 PAPIERROR( "pfm_create_evtsets(%d,%p,%d): %s", ctl->ctx_fd, &set,
1178 ctl->num_sets, strerror( ret ) );
1179 return ( PAPI_ESYS );
1180 }
1181 DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( &set, 1 ) );
1182 }
1183
1184 return PAPI_OK;
1185}
os_err_t pfm_stop(int fd)
os_err_t pfm_unload_context(int fd)
os_err_t pfm_delete_evtsets(int fd, pfarg_setdesc_t *setd, int count)
#define PFMLIB_ERR_NOTSUPP
Definition: pfmlib.h:284
Here is the call graph for this function:

◆ _papi_pfm_stop_profiling()

static int _papi_pfm_stop_profiling ( ThreadInfo_t thread,
EventSetInfo_t ESI 
)
static

Definition at line 1876 of file perfmon2/perfmon.c.

1877{
1878 ( void ) ESI; /*unused */
1879 /* Process any remaining samples in the sample buffer */
1880 return ( process_smpl_buf( 0, sizeof ( pfm_dfl_smpl_entry_t ), &thread ) );
1881}
Here is the call graph for this function:

◆ _papi_pfm_update_control_state()

static int _papi_pfm_update_control_state ( hwd_control_state_t ctl0,
NativeInfo_t native,
int  count,
hwd_context_t ctx0 
)
static

Definition at line 2139 of file perfmon2/perfmon.c.

2142{
2143 pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
2144 pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
2145 int i = 0, ret;
2146 int last_reg_set = 0, reg_set_done = 0, offset = 0;
2147 pfmlib_input_param_t tmpin, *inp = &ctl->in;
2148 pfmlib_output_param_t tmpout, *outp = &ctl->out;
2149 pfarg_pmd_t *pd = ctl->pd;
2150
2151 if ( count == 0 ) {
2152 SUBDBG( "Called with count == 0\n" );
2153 inp->pfp_event_count = 0;
2154 outp->pfp_pmc_count = 0;
2155 memset( inp->pfp_events, 0x0, sizeof ( inp->pfp_events ) );
2156 return ( PAPI_OK );
2157 }
2158
2159 memcpy( &tmpin, inp, sizeof ( tmpin ) );
2160 memcpy( &tmpout, outp, sizeof ( tmpout ) );
2161
2162 for ( i = 0; i < count; i++ ) {
2163 SUBDBG
2164 ( "Stuffing native event index %d (code %#x) into input structure.\n",
2165 i, ( ( pfm_register_t * ) native[i].ni_bits )->event );
2166 memcpy( inp->pfp_events + i, native[i].ni_bits,
2167 sizeof ( pfmlib_event_t ) );
2168 }
2169 inp->pfp_event_count = count;
2170
2171 /* let the library figure out the values for the PMCS */
2172
2173 ret = compute_kernel_args( ctl );
2174 if ( ret != PAPI_OK ) {
2175 /* Restore values */
2176 memcpy( inp, &tmpin, sizeof ( tmpin ) );
2177 memcpy( outp, &tmpout, sizeof ( tmpout ) );
2178 return ( ret );
2179 }
2180
2181 /* Update the native structure, because the allocation is done here. */
2182
2183 last_reg_set = pd[0].reg_set;
2184 for ( i = 0; i < count; i++ ) {
2185 if ( pd[i].reg_set != last_reg_set ) {
2186 offset += reg_set_done;
2187 reg_set_done = 0;
2188 }
2189 reg_set_done++;
2190
2191 native[i].ni_position = i;
2192 SUBDBG( "native event index %d (code %#x) is at PMD offset %d\n", i,
2193 ( ( pfm_register_t * ) native[i].ni_bits )->event,
2194 native[i].ni_position );
2195 }
2196
2197 /* If structure has not yet been filled with a context, fill it
2198 from the thread's context. This should happen in init_control_state
2199 when we give that a *ctx argument */
2200
2201 if ( ctl->ctx == NULL ) {
2202 ctl->ctx = &ctx->ctx;
2203 ctl->ctx_fd = ctx->ctx_fd;
2204 ctl->load = &ctx->load;
2205 }
2206
2207 return ( PAPI_OK );
2208}
static long count
static int native
static int compute_kernel_args(hwd_control_state_t *ctl0)
pfmlib_event_t pfp_events[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:113
unsigned int pfp_pmc_count
Definition: pfmlib.h:127
Here is the call graph for this function:

◆ _papi_pfm_write()

int _papi_pfm_write ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long from 
)

Definition at line 936 of file perfmon2/perfmon.c.

938{
939 unsigned int i;
940 int ret;
941
942 /* Read could have clobbered the values */
943 for ( i = 0; i < ( ( pfm_control_state_t * ) ctl )->in.pfp_event_count;
944 i++ ) {
945 if ( ( ( pfm_control_state_t * ) ctl )->pd[i].
946 reg_flags & PFM_REGFL_OVFL_NOTIFY )
947 ( ( pfm_control_state_t * ) ctl )->pd[i].reg_value =
948 from[i] +
949 ( ( pfm_control_state_t * ) ctl )->pd[i].reg_long_reset;
950 else
951 ( ( pfm_control_state_t * ) ctl )->pd[i].reg_value = from[i];
952 }
953
954 ret =
956 ( pfm_control_state_t * ) ctl );
957 if ( ret != PAPI_OK )
958 return PAPI_ESYS;
959
960
961 return ( PAPI_OK );
962}
Here is the call graph for this function:

◆ _papi_pfm_write_pmcs()

int _papi_pfm_write_pmcs ( pfm_context_t ctx,
pfm_control_state_t ctl 
)

Definition at line 191 of file perfmon2/perfmon.c.

192{
193 ( void ) ctx; /*unused */
194 unsigned int i = 0;
195 int ret;
196
197 SUBDBG( "PFM_WRITE_PMCS(%d,%p,%d)\n", ctl->ctx_fd, ctl->pc,
198 ctl->out.pfp_pmc_count );
199 if ( ctl->out.pfp_pmc_count > PFM_MAX_PMCDS ) {
200 for ( i = 0; i < ctl->out.pfp_pmc_count - PFM_MAX_PMCDS;
201 i += PFM_MAX_PMCDS ) {
202 if ( ( ret =
203 pfm_write_pmcs( ctl->ctx_fd, ctl->pc + i,
204 PFM_MAX_PMCDS ) ) ) {
206 PAPIERROR( "pfm_write_pmcs(%d,%p,%d): %s", ctl->ctx_fd, ctl->pc,
207 ctl->out.pfp_pmc_count, strerror( ret ) );
208 return ( PAPI_ESYS );
209 }
210 }
212 }
213 if ( ( ret =
214 pfm_write_pmcs( ctl->ctx_fd, ctl->pc + i,
215 ctl->out.pfp_pmc_count - i ) ) ) {
217 PAPIERROR( "pfm_write_pmcs(%d,%p,%d): %s", ctl->ctx_fd, ctl->pc,
218 ctl->out.pfp_pmc_count, strerror( ret ) );
219 return ( PAPI_ESYS );
220 }
222
223 return PAPI_OK;
224}
static void dump_pmc(pfm_control_state_t *ctl)
os_err_t pfm_write_pmcs(int fd, pfarg_pmc_t *pmcs, int count)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ _papi_pfm_write_pmds()

int _papi_pfm_write_pmds ( pfm_context_t ctx,
pfm_control_state_t ctl 
)

Definition at line 227 of file perfmon2/perfmon.c.

228{
229 ( void ) ctx; /*unused */
230 unsigned int i = 0;
231 int ret;
232
233 SUBDBG( "PFM_WRITE_PMDS(%d,%p,%d)\n", ctl->ctx_fd, ctl->pd,
234 ctl->in.pfp_event_count );
235 if ( ctl->in.pfp_event_count > PFM_MAX_PMCDS ) {
236 for ( i = 0; i < ctl->in.pfp_event_count - PFM_MAX_PMCDS;
237 i += PFM_MAX_PMCDS ) {
238 if ( ( ret =
239 pfm_write_pmds( ctl->ctx_fd, ctl->pd + i,
240 PFM_MAX_PMCDS ) ) ) {
242 PAPIERROR( "pfm_write_pmds(%d,%p,%d): errno=%d %s", ctl->ctx_fd,
243 ctl->pd, ctl->in.pfp_event_count, errno,
244 strerror( ret ) );
245 perror( "pfm_write_pmds" );
246 return ( PAPI_ESYS );
247 }
248 }
250 }
251 if ( ( ret =
252 pfm_write_pmds( ctl->ctx_fd, ctl->pd + i,
253 ctl->in.pfp_event_count - i ) ) ) {
255 PAPIERROR( "pfm_write_pmds(%d,%p,%d): errno=%d %s", ctl->ctx_fd,
256 ctl->pd, ctl->in.pfp_event_count, errno, strerror( ret ) );
257 perror( "pfm_write_pmds" );
258 return ( PAPI_ESYS );
259 }
261
262 return PAPI_OK;
263}
os_err_t pfm_write_pmds(int fd, pfarg_pmd_t *pmds, int count)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ attach()

static int attach ( hwd_control_state_t ctl,
unsigned long  tid 
)
static

Definition at line 593 of file perfmon2/perfmon.c.

594{
595 pfarg_ctx_t *newctx = ( pfarg_ctx_t * ) malloc( sizeof ( pfarg_ctx_t ) );
596 pfarg_load_t *load_args =
597 ( pfarg_load_t * ) malloc( sizeof ( pfarg_load_t ) );
598 int ret;
599
600 if ( ( newctx == NULL ) || ( load_args == NULL ) )
601 return ( PAPI_ENOMEM );
602 memset( newctx, 0x0, sizeof ( *newctx ) );
603 memset( load_args, 0, sizeof ( *load_args ) );
604
605 /* Make sure the process exists and is being ptraced() */
606
607 ret = ptrace( PTRACE_ATTACH, tid, NULL, NULL );
608 if ( ret == 0 ) {
609 ptrace( PTRACE_DETACH, tid, NULL, NULL );
610 PAPIERROR( "Process/thread %d is not being ptraced", tid );
611 free( newctx );
612 free( load_args );
613 return ( PAPI_EINVAL );
614 }
615 /* If we get here, then we should hope that the process is being
616 ptraced, if not, then we probably can't attach to it. */
617
618 if ( ( ret == -1 ) && ( errno != EPERM ) ) {
619 PAPIERROR( "Process/thread %d cannot be ptraced: %s", tid,
620 strerror( errno ) );
621 free( newctx );
622 free( load_args );
623 return ( PAPI_EINVAL );
624 }
625
626 SUBDBG( "PFM_CREATE_CONTEXT(%p,%p,%p,%d)\n", newctx, NULL, NULL, 0 );
627 if ( ( ret = pfm_create_context( newctx, NULL, NULL, 0 ) ) == -1 ) {
628 PAPIERROR( "attach:pfm_create_context(): %s", strerror( errno ) );
629 free( newctx );
630 free( load_args );
631 return ( PAPI_ESYS );
632 }
633 SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", ret );
634 tune_up_fd( ret );
635
636 ( ( pfm_control_state_t * ) ctl )->ctx_fd = ret;
637 ( ( pfm_control_state_t * ) ctl )->ctx = newctx;
638 load_args->load_pid = tid;
639 ( ( pfm_control_state_t * ) ctl )->load = load_args;
640
641 return ( PAPI_OK );
642}
#define PAPI_ENOMEM
Definition: f90papi.h:16
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_multiplex_timeout()

static int check_multiplex_timeout ( int  ctx_fd,
unsigned long timeout_ns 
)
static

Definition at line 306 of file perfmon2/perfmon.c.

307{
308 int ret;
309 pfarg_setdesc_t set[2];
310
311 memset( set, 0, sizeof ( pfarg_setdesc_t ) * 2 );
312 set[1].set_id = 1;
314 set[1].set_timeout = *timeout_ns;
315 SUBDBG( "Multiplexing interval requested is %llu ns.\n",
316 ( unsigned long long ) set[1].set_timeout );
317
318 /* Create a test eventset */
319
320 SUBDBG( "PFM_CREATE_EVTSETS(%d,%p,1)\n", ctx_fd, &set[1] );
321 if ( ( ret = pfm_create_evtsets( ctx_fd, &set[1], 1 ) ) != PFMLIB_SUCCESS ) {
322 DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( &set[1], 1 ) );
323 PAPIERROR( "pfm_create_evtsets(%d,%p,%d): %s", ctx_fd, &set[1], 1,
324 strerror( ret ) );
325 return ( PAPI_ESYS );
326 }
327
328 SUBDBG( "Multiplexing interval returned is %llu ns.\n",
329 ( unsigned long long ) set[1].set_timeout );
330 *timeout_ns = set[1].set_timeout;
331
332 /* Delete the second eventset */
333
334 pfm_delete_evtsets( ctx_fd, &set[1], 1 );
335
336 return ( PAPI_OK );
337}
#define PFM_SETFL_TIME_SWITCH
uint32_t set_flags
Definition: perfmon_v2.h:79
uint64_t set_timeout
Definition: perfmon_v2.h:80
uint16_t set_id
Definition: perfmon_v2.h:77
Here is the call graph for this function:
Here is the caller graph for this function:

◆ compute_kernel_args()

static int compute_kernel_args ( hwd_control_state_t ctl0)
inlinestatic

Definition at line 400 of file perfmon2/perfmon.c.

401{
403 pfmlib_input_param_t *inp = &ctl->in;
404 pfmlib_output_param_t *outp = &ctl->out;
407#if 0
408 /* This will be used to fixup the overflow and sample args after re-allocation */
409 pfarg_pmd_t oldpd;
410#endif
411 pfarg_pmd_t *pd = ctl->pd;
412 pfarg_pmc_t *pc = ctl->pc;
413 pfarg_setdesc_t *sets = ctl->set;
414 pfarg_setinfo_t *setinfos = ctl->setinfo;
415 int *num_sets = &ctl->num_sets;
416 unsigned int set = 0;
417 int donepc = 0, donepd = 0, ret, j;
418 unsigned int i, dispatch_count = inp->pfp_event_count;
419 int togo = inp->pfp_event_count, done = 0;
420
421 /* Save old PD array so we can reconstruct certain flags. */
422 /* This can be removed when we have higher level code call */
423 /* set_profile,set_overflow etc when there is hardware */
424 /* (component) support, but this change won't happen for PAPI 3.5 */
425
426 SUBDBG
427 ( "entry multiplexed %d, pfp_event_count %d, num_cntrs %d, num_sets %d\n",
429 *num_sets );
430 if ( ( ctl->multiplexed ) &&
431 ( inp->pfp_event_count >
432 ( unsigned int ) _perfmon2_vector.cmp_info.num_cntrs ) ) {
433 dispatch_count = _perfmon2_vector.cmp_info.num_cntrs;
434 }
435
436 while ( togo ) {
437 again:
438 memset( &tmpin, 0x0, sizeof ( tmpin ) );
439 memset( &tmpout, 0x0, sizeof ( tmpout ) );
440
441 SUBDBG( "togo %d, done %d, dispatch_count %d, num_cntrs %d\n", togo,
442 done, dispatch_count, _perfmon2_vector.cmp_info.num_cntrs );
443 tmpin.pfp_event_count = dispatch_count;
444 tmpin.pfp_dfl_plm = inp->pfp_dfl_plm;
445
446 /* Make sure we tell dispatch that these PMC's are not available */
449
450 for ( i = 0, j = done; i < dispatch_count; i++, j++ ) {
451 memcpy( tmpin.pfp_events + i, inp->pfp_events + j,
452 sizeof ( pfmlib_event_t ) );
453 }
454
455 if ( ( ret =
456 pfm_dispatch_events( &tmpin, NULL, &tmpout,
457 NULL ) ) != PFMLIB_SUCCESS ) {
458 if ( ctl->multiplexed ) {
459 dispatch_count--;
460 if ( dispatch_count == 0 ) {
461 PAPIERROR( "pfm_dispatch_events(): %s",
462 pfm_strerror( ret ) );
463 return ( _papi_libpfm_error( ret ) );
464 }
465 SUBDBG
466 ( "Dispatch failed because of counter conflict, trying again with %d counters.\n",
467 dispatch_count );
468 goto again;
469 }
470 PAPIERROR( "pfm_dispatch_events(): %s", pfm_strerror( ret ) );
471 return ( _papi_libpfm_error( ret ) );
472 }
473
474 /*
475 * Now prepare the argument to initialize the PMDs and PMCS.
476 * We must pfp_pmc_count to determine the number of PMC to intialize.
477 * We must use pfp_event_count to determine the number of PMD to initialize.
478 * Some events causes extra PMCs to be used, so pfp_pmc_count may be >= pfp_event_count.
479 *
480 * This step is new compared to libpfm-2.x. It is necessary because the library no
481 * longer knows about the kernel data structures.
482 */
483
484 for ( i = 0; i < tmpout.pfp_pmc_count; i++, donepc++ ) {
485 pc[donepc].reg_num = tmpout.pfp_pmcs[i].reg_num;
486 pc[donepc].reg_value = tmpout.pfp_pmcs[i].reg_value;
487 pc[donepc].reg_set = set;
488 SUBDBG( "PC%d (i%d) is reg num %d, value %llx, set %d\n", donepc, i,
489 pc[donepc].reg_num,
490 ( unsigned long long ) pc[donepc].reg_value,
491 pc[donepc].reg_set );
492 }
493
494 /* figure out pmd mapping from output pmc */
495
496#if defined(HAVE_PFM_REG_EVT_IDX)
497 for ( i = 0, j = 0; i < tmpin.pfp_event_count; i++, donepd++ ) {
498 pd[donepd].reg_num = tmpout.pfp_pmcs[j].reg_pmd_num;
499 pd[donepd].reg_set = set;
500 SUBDBG( "PD%d (i%d,j%d) is reg num %d, set %d\n", donepd, i, j,
501 pd[donepd].reg_num, pd[donepd].reg_set );
502
503 /* Skip over entries that map to the same PMD,
504 PIV has 2 PMCS for every PMD */
505
506 for ( ; j < tmpout.pfp_pmc_count; j++ )
507 if ( tmpout.pfp_pmcs[j].reg_evt_idx != i )
508 break;
509 }
510#else
511 for ( i = 0; i < tmpout.pfp_pmd_count; i++, donepd++ ) {
512 pd[donepd].reg_num = tmpout.pfp_pmds[i].reg_num;
513 pd[donepd].reg_set = set;
514 SUBDBG( "PD%d (i%d) is reg num %d, set %d\n", donepd, i,
515 pd[donepd].reg_num, pd[donepd].reg_set );
516 }
517#endif
518
519 togo -= dispatch_count;
520 done += dispatch_count;
522 dispatch_count = _perfmon2_vector.cmp_info.num_cntrs;
523 else
524 dispatch_count = togo;
525
526 setinfos[set].set_id = set;
527 sets[set].set_id = set;
528 set++;
529 }
530
531 *num_sets = set;
532 outp->pfp_pmc_count = donepc;
533
534 if ( ctl->multiplexed && ( set > 1 ) ) {
535 for ( i = 0; i < set; i++ ) {
537 sets[i].set_timeout = ctl->multiplexed;
538 }
539 }
540 SUBDBG
541 ( "exit multiplexed %d (ns switch time), pfp_pmc_count %d, num_sets %d\n",
542 ctl->multiplexed, outp->pfp_pmc_count, *num_sets );
543 return ( PAPI_OK );
544}
int _papi_libpfm_error(int pfm_error)
char * pfm_strerror(int code)
pfm_err_t pfm_dispatch_events(pfmlib_input_param_t *p, void *model_in, pfmlib_output_param_t *q, void *model_out)
uint16_t reg_set
Definition: perfmon_v2.h:29
uint16_t reg_num
Definition: perfmon_v2.h:28
uint64_t reg_value
Definition: perfmon_v2.h:31
uint16_t set_id
Definition: perfmon_v2.h:85
unsigned int pfp_dfl_plm
Definition: pfmlib.h:110
pfmlib_regmask_t pfp_unavail_pmcs
Definition: pfmlib.h:114
pfmlib_reg_t pfp_pmds[PFMLIB_MAX_PMDS]
Definition: pfmlib.h:130
pfmlib_reg_t pfp_pmcs[PFMLIB_MAX_PMCS]
Definition: pfmlib.h:129
unsigned int pfp_pmd_count
Definition: pfmlib.h:128
unsigned long long reg_value
Definition: pfmlib.h:98
unsigned int reg_num
Definition: pfmlib.h:100
Here is the call graph for this function:
Here is the caller graph for this function:

◆ detach()

static int detach ( hwd_context_t ctx,
hwd_control_state_t ctl 
)
static

Definition at line 645 of file perfmon2/perfmon.c.

646{
647 int i;
648
649 i = close( ( ( pfm_control_state_t * ) ctl )->ctx_fd );
650 SUBDBG( "CLOSE fd %d returned %d\n",
651 ( ( pfm_control_state_t * ) ctl )->ctx_fd, i );
652 (void) i;
653
654 /* Restore to main threads context */
655 free( ( ( pfm_control_state_t * ) ctl )->ctx );
656 ( ( pfm_control_state_t * ) ctl )->ctx = &( ( pfm_context_t * ) ctx )->ctx;
657 ( ( pfm_control_state_t * ) ctl )->ctx_fd =
658 ( ( pfm_context_t * ) ctx )->ctx_fd;
659 free( ( ( pfm_control_state_t * ) ctl )->load );
660 ( ( pfm_control_state_t * ) ctl )->load =
661 &( ( pfm_context_t * ) ctx )->load;
662
663 return ( PAPI_OK );
664}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ detect_timeout_and_unavail_pmu_regs()

static int detect_timeout_and_unavail_pmu_regs ( pfmlib_regmask_t r_pmcs,
pfmlib_regmask_t r_pmds,
unsigned long timeout_ns 
)
static

Definition at line 341 of file perfmon2/perfmon.c.

344{
345 pfarg_ctx_t ctx;
346 pfarg_setinfo_t setf;
347 unsigned int i;
348 int ret, j, myfd;
349
350 memset( r_pmcs, 0, sizeof ( *r_pmcs ) );
351 memset( r_pmds, 0, sizeof ( *r_pmds ) );
352
353 memset( &ctx, 0, sizeof ( ctx ) );
354 memset( &setf, 0, sizeof ( setf ) );
355 /*
356 * if no context descriptor is passed, then create
357 * a temporary context
358 */
359 SUBDBG( "PFM_CREATE_CONTEXT(%p,%p,%p,%d)\n", &ctx, NULL, NULL, 0 );
360 myfd = pfm_create_context( &ctx, NULL, NULL, 0 );
361 if ( myfd == -1 ) {
362 PAPIERROR( "detect_unavail_pmu_regs:pfm_create_context(): %s",
363 strerror( errno ) );
364 return ( PAPI_ESYS );
365 }
366 SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", myfd );
367 /*
368 * retrieve available register bitmasks from set0
369 * which is guaranteed to exist for every context
370 */
371 ret = pfm_getinfo_evtsets( myfd, &setf, 1 );
372 if ( ret != PFMLIB_SUCCESS ) {
373 PAPIERROR( "pfm_getinfo_evtsets(): %s", strerror( ret ) );
374 return ( PAPI_ESYS );
375 }
376 DEBUGCALL( DEBUG_SUBSTRATE, dump_setinfo( &setf, 1 ) );
377 if ( r_pmcs )
378 for ( i = 0; i < PFM_PMC_BV; i++ ) {
379 for ( j = 0; j < 64; j++ ) {
380 if ( ( setf.set_avail_pmcs[i] & ( 1ULL << j ) ) == 0 )
381 pfm_regmask_set( r_pmcs, ( i << 6 ) + j );
382 }
383 }
384 if ( r_pmds )
385 for ( i = 0; i < PFM_PMD_BV; i++ ) {
386 for ( j = 0; j < 64; j++ ) {
387 if ( ( setf.set_avail_pmds[i] & ( 1ULL << j ) ) == 0 )
388 pfm_regmask_set( r_pmds, ( i << 6 ) + j );
389 }
390 }
391 check_multiplex_timeout( myfd, timeout_ns );
392 i = close( myfd );
393 SUBDBG( "CLOSE fd %d returned %d\n", myfd, i );
394 return PAPI_OK;
395}
static int check_multiplex_timeout(int ctx_fd, unsigned long *timeout_ns)
static int pfm_regmask_set(pfmlib_regmask_t *h, unsigned int b)
Definition: pfmlib.h:321
uint64_t set_avail_pmcs[PFM_PMC_BV]
Definition: perfmon_v2.h:92
uint64_t set_avail_pmds[PFM_PMD_BV]
Definition: perfmon_v2.h:93
Here is the call graph for this function:
Here is the caller graph for this function:

◆ dump_pmc()

static void dump_pmc ( pfm_control_state_t ctl)
static

Definition at line 108 of file perfmon2/perfmon.c.

109{
110 unsigned int i;
111 pfarg_pmc_t *pc = ctl->pc;
112
113 for ( i = 0; i < ctl->out.pfp_pmc_count; i++ ) {
114 SUBDBG( "PC[%d]\n", i );
115 SUBDBG( "PC[%d].reg_num = %d\n", i, pc[i].reg_num );
116 SUBDBG( "PC[%d].reg_set = %d\n", i, pc[i].reg_set );
117 SUBDBG( "PC[%d].reg_flags = %#08x\n", i, pc[i].reg_flags );
118 SUBDBG( "PC[%d].reg_value = %#016llx\n", i,
119 ( unsigned long long ) pc[i].reg_value );
120 }
121}
Here is the caller graph for this function:

◆ dump_pmd()

static void dump_pmd ( pfm_control_state_t ctl)
static

Definition at line 124 of file perfmon2/perfmon.c.

125{
126 unsigned int i;
127 pfarg_pmd_t *pd = ctl->pd;
128
129 for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
130 SUBDBG( "PD[%d]\n", i );
131 SUBDBG( "PD[%d].reg_num = %d\n", i, pd[i].reg_num );
132 SUBDBG( "PD[%d].reg_set = %d\n", i, pd[i].reg_set );
133 SUBDBG( "PD[%d].reg_flags = %#08x\n", i, pd[i].reg_flags );
134 SUBDBG( "PD[%d].reg_value = %#016llx\n", i,
135 ( unsigned long long ) pd[i].reg_value );
136 SUBDBG( "PD[%d].reg_long_reset = %llu\n", i,
137 ( unsigned long long ) pd[i].reg_long_reset );
138 SUBDBG( "PD[%d].reg_short_reset = %llu\n", i,
139 ( unsigned long long ) pd[i].reg_short_reset );
140 SUBDBG( "PD[%d].reg_last_reset_val = %llu\n", i,
141 ( unsigned long long ) pd[i].reg_last_reset_val );
142 SUBDBG( "PD[%d].reg_ovfl_switch_cnt = %llu\n", i,
143 ( unsigned long long ) pd[i].reg_ovfl_switch_cnt );
144 SUBDBG( "PD[%d].reg_reset_pmds[0] = %#016llx\n", i,
145 ( unsigned long long ) pd[i].reg_reset_pmds[0] );
146 SUBDBG( "PD[%d].reg_smpl_pmds[0] = %#016llx\n", i,
147 ( unsigned long long ) pd[i].reg_smpl_pmds[0] );
148 SUBDBG( "PD[%d].reg_smpl_eventid = %llu\n", i,
149 ( unsigned long long ) pd[i].reg_smpl_eventid );
150 SUBDBG( "PD[%d].reg_random_mask = %llu\n", i,
151 ( unsigned long long ) pd[i].reg_random_mask );
152 SUBDBG( "PD[%d].reg_random_seed = %d\n", i, pd[i].reg_random_seed );
153 }
154}
Here is the caller graph for this function:

◆ dump_setinfo()

static void dump_setinfo ( pfarg_setinfo_t setinfo,
int  num_sets 
)
static

Definition at line 82 of file perfmon2/perfmon.c.

83{
84 int i;
85
86 for ( i = 0; i < num_sets; i++ ) {
87 SUBDBG( "SETINFO[%d]\n", i );
88 SUBDBG( "SETINFO[%d].set_id = %d\n", i, setinfo[i].set_id );
89 // SUBDBG("SETINFO[%d].set_id_next = %d\n",i,setinfo[i].set_id_next);
90 SUBDBG( "SETINFO[%d].set_flags = %d\n", i, setinfo[i].set_flags );
91 SUBDBG( "SETINFO[%d].set_ovfl_pmds[0] = %#016llx\n", i,
92 ( unsigned long long ) setinfo[i].set_ovfl_pmds[0] );
93 SUBDBG( "SETINFO[%d].set_runs = %llu\n", i,
94 ( unsigned long long ) setinfo[i].set_runs );
95 SUBDBG( "SETINFO[%d].set_timeout = %llu\n", i,
96 ( unsigned long long ) setinfo[i].set_timeout );
97 SUBDBG( "SETINFO[%d].set_act_duration = %llu\n", i,
98 ( unsigned long long ) setinfo[i].set_act_duration );
99 // SUBDBG("SETINFO[%d].set_mmap_offset = %#016llx\n",i,(unsigned long long)setinfo[i].set_mmap_offset);
100 SUBDBG( "SETINFO[%d].set_avail_pmcs[0] = %#016llx\n", i,
101 ( unsigned long long ) setinfo[i].set_avail_pmcs[0] );
102 SUBDBG( "SETINFO[%d].set_avail_pmds[0] = %#016llx\n", i,
103 ( unsigned long long ) setinfo[i].set_avail_pmds[0] );
104 }
105}
Here is the caller graph for this function:

◆ dump_sets()

static void dump_sets ( pfarg_setdesc_t set,
int  num_sets 
)
static

Definition at line 66 of file perfmon2/perfmon.c.

67{
68 int i;
69
70 for ( i = 0; i < num_sets; i++ ) {
71 SUBDBG( "SET[%d]\n", i );
72 SUBDBG( "SET[%d].set_id = %d\n", i, set[i].set_id );
73 // SUBDBG("SET[%d].set_id_next = %d\n",i,set[i].set_id_next);
74 SUBDBG( "SET[%d].set_flags = %d\n", i, set[i].set_flags );
75 SUBDBG( "SET[%d].set_timeout = %llu\n", i,
76 ( unsigned long long ) set[i].set_timeout );
77 // SUBDBG("SET[%d].set_mmap_offset = %#016llx\n",i,(unsigned long long)set[i].set_mmap_offset);
78 }
79}
Here is the caller graph for this function:

◆ dump_smpl()

static void dump_smpl ( pfm_dfl_smpl_entry_t entry)
static

Definition at line 174 of file perfmon2/perfmon.c.

175{
176 SUBDBG( "SMPL.pid = %d\n", entry->pid );
177 SUBDBG( "SMPL.ovfl_pmd = %d\n", entry->ovfl_pmd );
178 SUBDBG( "SMPL.last_reset_val = %llu\n",
179 ( unsigned long long ) entry->last_reset_val );
180 SUBDBG( "SMPL.ip = %#llx\n", ( unsigned long long ) entry->ip );
181 SUBDBG( "SMPL.tstamp = %llu\n", ( unsigned long long ) entry->tstamp );
182 SUBDBG( "SMPL.cpu = %d\n", entry->cpu );
183 SUBDBG( "SMPL.set = %d\n", entry->set );
184 SUBDBG( "SMPL.tgid = %d\n", entry->tgid );
185}
uint32_t tgid
uint64_t ip
uint16_t cpu
uint32_t pid
uint16_t set
uint64_t last_reset_val
uint64_t tstamp
uint16_t ovfl_pmd
Here is the caller graph for this function:

◆ dump_smpl_arg()

static void dump_smpl_arg ( pfm_dfl_smpl_arg_t arg)
static

Definition at line 58 of file perfmon2/perfmon.c.

59{
60 SUBDBG( "SMPL_ARG.buf_size = %llu\n",
61 ( unsigned long long ) arg->buf_size );
62 SUBDBG( "SMPL_ARG.buf_flags = %d\n", arg->buf_flags );
63}
Here is the caller graph for this function:

◆ dump_smpl_hdr()

static void dump_smpl_hdr ( pfm_dfl_smpl_hdr_t hdr)
static

Definition at line 157 of file perfmon2/perfmon.c.

158{
159 SUBDBG( "SMPL_HDR.hdr_count = %llu\n",
160 ( unsigned long long ) hdr->hdr_count );
161 SUBDBG( "SMPL_HDR.hdr_cur_offs = %llu\n",
162 ( unsigned long long ) hdr->hdr_cur_offs );
163 SUBDBG( "SMPL_HDR.hdr_overflows = %llu\n",
164 ( unsigned long long ) hdr->hdr_overflows );
165 SUBDBG( "SMPL_HDR.hdr_buf_size = %llu\n",
166 ( unsigned long long ) hdr->hdr_buf_size );
167 SUBDBG( "SMPL_HDR.hdr_min_buf_space = %llu\n",
168 ( unsigned long long ) hdr->hdr_min_buf_space );
169 SUBDBG( "SMPL_HDR.hdr_version = %d\n", hdr->hdr_version );
170 SUBDBG( "SMPL_HDR.hdr_buf_flags = %d\n", hdr->hdr_buf_flags );
171}
Here is the caller graph for this function:

◆ find_profile_index()

static int find_profile_index ( EventSetInfo_t ESI,
int  pmd,
int flags,
unsigned int native_index,
int profile_index 
)
inlinestatic

Definition at line 1312 of file perfmon2/perfmon.c.

1314{
1315 int pos, esi_index, count;
1317 pfarg_pmd_t *pd;
1318 unsigned int i;
1319
1320 pd = ctl->pd;
1321
1322 /* Find virtual PMD index, the one we actually read from the physical PMD number that
1323 overflowed. This index is the one related to the profile buffer. */
1324
1325 for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
1326 if ( pd[i].reg_num == pmd ) {
1327 SUBDBG( "Physical PMD %d is Virtual PMD %d\n", pmd, i );
1328 pmd = i;
1329 break;
1330 }
1331 }
1332
1333
1334 SUBDBG( "(%p,%d,%p)\n", ESI, pmd, index );
1335
1336 for ( count = 0; count < ESI->profile.event_counter; count++ ) {
1337 /* Find offset of PMD that gets read from the kernel */
1338 esi_index = ESI->profile.EventIndex[count];
1339 pos = ESI->EventInfoArray[esi_index].pos[0];
1340 SUBDBG( "Examining event at ESI index %d, PMD position %d\n", esi_index,
1341 pos );
1342 // PMU_FIRST_COUNTER
1343 if ( pos == pmd ) {
1344 *profile_index = count;
1345 *native_index =
1347 *flags = ESI->profile.flags;
1348 SUBDBG( "Native event %d is at profile index %d, flags %d\n",
1349 *native_index, *profile_index, *flags );
1350 return ( PAPI_OK );
1351 }
1352 }
1353
1354 PAPIERROR( "wrong count: %d vs. ESI->profile.event_counter %d", count,
1355 ESI->profile.event_counter );
1356 return ( PAPI_EBUG );
1357}
#define PAPI_EBUG
Definition: f90papi.h:176
#define PAPI_NATIVE_AND_MASK
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_string_from_file()

static int get_string_from_file ( char *  file,
char *  str,
int  len 
)
static

Definition at line 731 of file perfmon2/perfmon.c.

732{
733 FILE *f = fopen( file, "r" );
735 if ( f == NULL ) {
736 PAPIERROR( "fopen(%s): %s", file, strerror( errno ) );
737 return ( PAPI_ESYS );
738 }
739 if ( fscanf( f, "%s\n", buf ) != 1 ) {
740 PAPIERROR( "fscanf(%s, %%s\\n): Unable to scan 1 token", file );
741 fclose( f );
742 return PAPI_ESYS;
743 }
744 strncpy( str, buf, ( len > PAPI_HUGE_STR_LEN ? PAPI_HUGE_STR_LEN : len ) );
745 fclose( f );
746 return ( PAPI_OK );
747}
double f(double a)
Definition: cpi.c:23
int fclose(FILE *__stream)
const char FILE * file
Definition: pscanf.h:13
Here is the call graph for this function:
Here is the caller graph for this function:

◆ pfm_bv_set()

static void pfm_bv_set ( uint64_t *  bv,
uint16_t  rnum 
)
inlinestatic

Definition at line 1401 of file perfmon2/perfmon.c.

1402{
1403 bv[rnum >> LBPL] |= 1UL << ( rnum & ( BPL - 1 ) );
1404}
#define LBPL
#define BPL
Here is the caller graph for this function:

◆ process_smpl_buf()

static int process_smpl_buf ( int  num_smpl_pmds,
int  entry_size,
ThreadInfo_t **  thr 
)
inlinestatic

Definition at line 1690 of file perfmon2/perfmon.c.

1691{
1692 ( void ) num_smpl_pmds; /*unused */
1693 ( void ) entry_size; /*unused */
1696 uint64_t entry, count;
1697 pfm_dfl_smpl_hdr_t *hdr =
1698 ( ( pfm_context_t * ) ( *thr )->context[cidx] )->smpl_buf;
1699 int ret, profile_index, flags;
1700 unsigned int native_pfm_index;
1701 vptr_t pc = NULL;
1702 long long weight;
1703
1705 count = hdr->hdr_count;
1706 ent = ( pfm_dfl_smpl_entry_t * ) ( hdr + 1 );
1707 entry = 0;
1708
1709 SUBDBG( "This buffer has %llu samples in it.\n",
1710 ( unsigned long long ) count );
1711 while ( count-- ) {
1712 SUBDBG( "Processing sample entry %llu\n",
1713 ( unsigned long long ) entry );
1715
1716 /* Find the index of the profile buffers if we are profiling on many events */
1717
1718 ret =
1719 find_profile_index( ( *thr )->running_eventset[cidx], ent->ovfl_pmd,
1720 &flags, &native_pfm_index, &profile_index );
1721 if ( ret != PAPI_OK )
1722 return ( ret );
1723
1724 weight = process_smpl_entry( native_pfm_index, flags, &ent, &pc );
1725
1726 _papi_hwi_dispatch_profile( ( *thr )->running_eventset[cidx], pc,
1727 weight, profile_index );
1728
1729 entry++;
1730 }
1731 return ( PAPI_OK );
1732}
void _papi_hwi_dispatch_profile(EventSetInfo_t *ESI, vptr_t pc, long long over, int profile_index)
Definition: extras.c:165
static int process_smpl_entry(unsigned int native_pfm_index, int flags, pfm_dfl_smpl_entry_t **ent, vptr_t *pc)
static int find_profile_index(EventSetInfo_t *ESI, int pmd, int *flags, unsigned int *native_index, int *profile_index)
static void dump_smpl(pfm_dfl_smpl_entry_t *entry)
static void dump_smpl_hdr(pfm_dfl_smpl_hdr_t *hdr)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ process_smpl_entry()

static int process_smpl_entry ( unsigned int  native_pfm_index,
int  flags,
pfm_dfl_smpl_entry_t **  ent,
vptr_t pc 
)
inlinestatic

Definition at line 1448 of file perfmon2/perfmon.c.

1450{
1451#ifndef __ia64__
1452 ( void ) native_pfm_index; /*unused */
1453 ( void ) flags; /*unused */
1454#endif
1455 SUBDBG( "process_smpl_entry(%d,%d,%p,%p)\n", native_pfm_index, flags, ent,
1456 pc );
1457
1458#ifdef __ia64__
1459 /* Fixup EAR stuff here */
1460 if ( is_montecito_and_dear( native_pfm_index ) ) {
1461 pfm_mont_pmd_reg_t data_addr;
1462 pfm_mont_pmd_reg_t latency;
1463 pfm_mont_pmd_reg_t load_addr;
1464 unsigned long newent;
1465
1466 if ( ( flags & ( PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR ) ) == 0 )
1467 goto safety;
1468
1469 /* Skip the header */
1470 ++( *ent );
1471
1472 // PMD32 has data address on Montecito
1473 // PMD33 has latency on Montecito
1474 // PMD36 has instruction address on Montecito
1475 data_addr = *( pfm_mont_pmd_reg_t * ) * ent;
1476 latency =
1477 *( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
1478 sizeof ( data_addr ) );
1479 load_addr =
1480 *( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
1481 sizeof ( data_addr ) +
1482 sizeof ( latency ) );
1483
1484 SUBDBG( "PMD[32]: %#016llx\n",
1485 ( unsigned long long ) data_addr.pmd_val );
1486 SUBDBG( "PMD[33]: %#016llx\n",
1487 ( unsigned long long ) latency.pmd_val );
1488 SUBDBG( "PMD[36]: %#016llx\n",
1489 ( unsigned long long ) load_addr.pmd_val );
1490
1491 if ( ( !load_addr.pmd36_mont_reg.dear_vl ) ||
1492 ( !load_addr.pmd33_mont_reg.dear_stat ) ) {
1493 SUBDBG
1494 ( "Invalid DEAR sample found, dear_vl = %d, dear_stat = %#x\n",
1495 load_addr.pmd36_mont_reg.dear_vl,
1496 load_addr.pmd33_mont_reg.dear_stat );
1497 bail1:
1498 newent = ( unsigned long ) *ent;
1499 newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
1500 *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1501 return 0;
1502 }
1503
1504 if ( flags & PAPI_PROFIL_DATA_EAR )
1505 *pc = ( vptr_t ) data_addr.pmd_val;
1506 else if ( flags & PAPI_PROFIL_INST_EAR ) {
1507 unsigned long tmp =
1508 ( ( load_addr.pmd36_mont_reg.dear_iaddr +
1509 ( unsigned long ) load_addr.pmd36_mont_reg.
1510 dear_bn ) << 4 ) | ( unsigned long ) load_addr.
1511 pmd36_mont_reg.dear_slot;
1512 *pc = ( vptr_t ) tmp;
1513 } else {
1514 PAPIERROR( "BUG!" );
1515 goto bail1;
1516 }
1517
1518 newent = ( unsigned long ) *ent;
1519 newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
1520 *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1521 return 0;
1522 } else if ( is_montecito_and_iear( native_pfm_index ) ) {
1523 pfm_mont_pmd_reg_t latency;
1524 pfm_mont_pmd_reg_t icache_line_addr;
1525 unsigned long newent;
1526
1527 if ( ( flags & PAPI_PROFIL_INST_EAR ) == 0 )
1528 goto safety;
1529
1530 /* Skip the header */
1531 ++( *ent );
1532
1533 // PMD34 has data address on Montecito
1534 // PMD35 has latency on Montecito
1535 icache_line_addr = *( pfm_mont_pmd_reg_t * ) * ent;
1536 latency =
1537 *( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
1538 sizeof ( icache_line_addr ) );
1539
1540 SUBDBG( "PMD[34]: %#016llx\n",
1541 ( unsigned long long ) icache_line_addr.pmd_val );
1542 SUBDBG( "PMD[35]: %#016llx\n",
1543 ( unsigned long long ) latency.pmd_val );
1544
1545 if ( ( icache_line_addr.pmd34_mont_reg.iear_stat & 0x1 ) == 0 ) {
1546 SUBDBG( "Invalid IEAR sample found, iear_stat = %#x\n",
1547 icache_line_addr.pmd34_mont_reg.iear_stat );
1548 bail2:
1549 newent = ( unsigned long ) *ent;
1550 newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
1551 *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1552 return ( 0 );
1553 }
1554
1555 if ( flags & PAPI_PROFIL_INST_EAR ) {
1556 unsigned long tmp = icache_line_addr.pmd34_mont_reg.iear_iaddr << 5;
1557 *pc = ( vptr_t ) tmp;
1558 } else {
1559 PAPIERROR( "BUG!" );
1560 goto bail2;
1561 }
1562
1563 newent = ( unsigned long ) *ent;
1564 newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
1565 *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1566 return 0;
1567 } else if ( is_itanium2_and_dear( native_pfm_index ) ) {
1568 pfm_ita2_pmd_reg_t data_addr;
1569 pfm_ita2_pmd_reg_t latency;
1570 pfm_ita2_pmd_reg_t load_addr;
1571 unsigned long newent;
1572
1573 if ( ( flags & ( PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR ) ) == 0 )
1574 goto safety;
1575
1576 /* Skip the header */
1577 ++( *ent );
1578
1579 // PMD2 has data address on Itanium 2
1580 // PMD3 has latency on Itanium 2
1581 // PMD17 has instruction address on Itanium 2
1582 data_addr = *( pfm_ita2_pmd_reg_t * ) * ent;
1583 latency =
1584 *( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
1585 sizeof ( data_addr ) );
1586 load_addr =
1587 *( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
1588 sizeof ( data_addr ) +
1589 sizeof ( latency ) );
1590
1591 SUBDBG( "PMD[2]: %#016llx\n",
1592 ( unsigned long long ) data_addr.pmd_val );
1593 SUBDBG( "PMD[3]: %#016llx\n", ( unsigned long long ) latency.pmd_val );
1594 SUBDBG( "PMD[17]: %#016llx\n",
1595 ( unsigned long long ) load_addr.pmd_val );
1596
1597 if ( ( !load_addr.pmd17_ita2_reg.dear_vl ) ||
1598 ( !load_addr.pmd3_ita2_reg.dear_stat ) ) {
1599 SUBDBG
1600 ( "Invalid DEAR sample found, dear_vl = %d, dear_stat = %#x\n",
1601 load_addr.pmd17_ita2_reg.dear_vl,
1602 load_addr.pmd3_ita2_reg.dear_stat );
1603 bail3:
1604 newent = ( unsigned long ) *ent;
1605 newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
1606 *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1607 return 0;
1608 }
1609
1610 if ( flags & PAPI_PROFIL_DATA_EAR )
1611 *pc = ( vptr_t ) data_addr.pmd_val;
1612 else if ( flags & PAPI_PROFIL_INST_EAR ) {
1613 unsigned long tmp =
1614 ( ( load_addr.pmd17_ita2_reg.dear_iaddr +
1615 ( unsigned long ) load_addr.pmd17_ita2_reg.
1616 dear_bn ) << 4 ) | ( unsigned long ) load_addr.
1617 pmd17_ita2_reg.dear_slot;
1618 *pc = ( vptr_t ) tmp;
1619 } else {
1620 PAPIERROR( "BUG!" );
1621 goto bail3;
1622 }
1623
1624 newent = ( unsigned long ) *ent;
1625 newent += 3 * sizeof ( pfm_ita2_pmd_reg_t );
1626 *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1627 return 0;
1628 } else if ( is_itanium2_and_iear( native_pfm_index ) ) {
1629 pfm_ita2_pmd_reg_t latency;
1630 pfm_ita2_pmd_reg_t icache_line_addr;
1631 unsigned long newent;
1632
1633 if ( ( flags & PAPI_PROFIL_INST_EAR ) == 0 )
1634 goto safety;
1635
1636 /* Skip the header */
1637 ++( *ent );
1638
1639 // PMD0 has address on Itanium 2
1640 // PMD1 has latency on Itanium 2
1641 icache_line_addr = *( pfm_ita2_pmd_reg_t * ) * ent;
1642 latency =
1643 *( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
1644 sizeof ( icache_line_addr ) );
1645
1646 SUBDBG( "PMD[0]: %#016llx\n",
1647 ( unsigned long long ) icache_line_addr.pmd_val );
1648 SUBDBG( "PMD[1]: %#016llx\n", ( unsigned long long ) latency.pmd_val );
1649
1650 if ( ( icache_line_addr.pmd0_ita2_reg.iear_stat & 0x1 ) == 0 ) {
1651 SUBDBG( "Invalid IEAR sample found, iear_stat = %#x\n",
1652 icache_line_addr.pmd0_ita2_reg.iear_stat );
1653 bail4:
1654 newent = ( unsigned long ) *ent;
1655 newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
1656 *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1657 return ( 0 );
1658 }
1659
1660 if ( flags & PAPI_PROFIL_INST_EAR ) {
1661 unsigned long tmp = icache_line_addr.pmd0_ita2_reg.iear_iaddr << 5;
1662 *pc = ( vptr_t ) tmp;
1663 } else {
1664 PAPIERROR( "BUG!" );
1665 goto bail4;
1666 }
1667
1668 newent = ( unsigned long ) *ent;
1669 newent += 2 * sizeof ( pfm_ita2_pmd_reg_t );
1670 *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1671 return 0;
1672 }
1673#if 0
1674 ( is_btb( native_pfm_index ) ) {
1675 // PMD48-63,39 on Montecito
1676 // PMD8-15,16 on Itanium 2
1677 }
1678#endif
1679 else
1680 safety:
1681#endif
1682 {
1683 *pc = ( vptr_t ) ( ( size_t ) ( ( *ent )->ip ) );
1684 ++( *ent );
1685 return ( 0 );
1686 }
1687}
#define is_btb(i)
if(file==NULL) goto out
struct pfm_ita2_pmd_reg_t::@54 pmd0_ita2_reg
unsigned long pmd_val
unsigned long dear_stat
unsigned long dear_slot
unsigned long iear_stat
unsigned long iear_iaddr
unsigned long dear_vl
struct pfm_ita2_pmd_reg_t::@61 pmd17_ita2_reg
struct pfm_ita2_pmd_reg_t::@57 pmd3_ita2_reg
unsigned long dear_iaddr
unsigned long dear_slot
struct pfm_mont_pmd_reg_t::@75 pmd33_mont_reg
unsigned long iear_stat
struct pfm_mont_pmd_reg_t::@76 pmd34_mont_reg
struct pfm_mont_pmd_reg_t::@78 pmd36_mont_reg
unsigned long iear_iaddr
unsigned long dear_iaddr
unsigned long dear_vl
unsigned long dear_stat
unsigned long pmd_val
Here is the call graph for this function:
Here is the caller graph for this function:

◆ round_requested_ns()

static int round_requested_ns ( int  ns)
inlinestatic

Definition at line 1188 of file perfmon2/perfmon.c.

1189{
1190 if ( ns <= _papi_os_info.itimer_res_ns ) {
1192 } else {
1193 int leftover_ns = ns % _papi_os_info.itimer_res_ns;
1194 return ( ns - leftover_ns + _papi_os_info.itimer_res_ns );
1195 }
1196}
PAPI_os_info_t _papi_os_info
Definition: aix.c:1210
Here is the caller graph for this function:

◆ set_domain()

static int set_domain ( hwd_control_state_t ctl0,
int  domain 
)
inlinestatic

Definition at line 667 of file perfmon2/perfmon.c.

668{
670 int mode = 0, did = 0;
671 pfmlib_input_param_t *inp = &ctl->in;
672
673 if ( domain & PAPI_DOM_USER ) {
674 did = 1;
675 mode |= PFM_PLM3;
676 }
677
678 if ( domain & PAPI_DOM_KERNEL ) {
679 did = 1;
680 mode |= PFM_PLM0;
681 }
682
683 if ( domain & PAPI_DOM_SUPERVISOR ) {
684 did = 1;
685 mode |= PFM_PLM1;
686 }
687
688 if ( domain & PAPI_DOM_OTHER ) {
689 did = 1;
690 mode |= PFM_PLM2;
691 }
692
693 if ( !did )
694 return ( PAPI_EINVAL );
695
696 inp->pfp_dfl_plm = mode;
697
698 return ( compute_kernel_args( ctl ) );
699}
#define PFM_PLM2
Definition: pfmlib.h:52
#define PFM_PLM3
Definition: pfmlib.h:53
#define PFM_PLM0
Definition: pfmlib.h:50
#define PFM_PLM1
Definition: pfmlib.h:51
Here is the call graph for this function:
Here is the caller graph for this function:

◆ set_granularity()

static int set_granularity ( hwd_control_state_t this_state,
int  domain 
)
inlinestatic

Definition at line 702 of file perfmon2/perfmon.c.

703{
704 ( void ) this_state; /*unused */
705 switch ( domain ) {
706 case PAPI_GRN_PROCG:
707 case PAPI_GRN_SYS:
708 case PAPI_GRN_SYS_CPU:
709 case PAPI_GRN_PROC:
710 return PAPI_ECMP;
711 case PAPI_GRN_THR:
712 break;
713 default:
714 return PAPI_EINVAL;
715 }
716 return PAPI_OK;
717}
#define PAPI_GRN_PROCG
Definition: f90papi.h:202
#define PAPI_ECMP
Definition: f90papi.h:214
#define PAPI_GRN_SYS
Definition: f90papi.h:43
#define PAPI_GRN_SYS_CPU
Definition: f90papi.h:100
#define PAPI_GRN_PROC
Definition: f90papi.h:266
#define PAPI_GRN_THR
Definition: f90papi.h:265
Here is the caller graph for this function:

◆ set_inherit()

static int set_inherit ( int  arg)
inlinestatic

Definition at line 724 of file perfmon2/perfmon.c.

725{
726 ( void ) arg; /*unused */
727 return PAPI_ECMP;
728}
Here is the caller graph for this function:

◆ setup_ear_event()

static int setup_ear_event ( unsigned int  native_index,
pfarg_pmd_t pd,
int  flags 
)
inlinestatic

Definition at line 1407 of file perfmon2/perfmon.c.

1408{
1409 ( void ) flags; /*unused */
1410#if defined(__ia64__)
1412 if ( pfm_mont_is_dear( native_index ) ) { /* 2,3,17 */
1413 pfm_bv_set( pd[0].reg_smpl_pmds, 32 );
1414 pfm_bv_set( pd[0].reg_smpl_pmds, 33 );
1415 pfm_bv_set( pd[0].reg_smpl_pmds, 36 );
1416 pfm_bv_set( pd[0].reg_reset_pmds, 36 );
1417 return ( 1 );
1418 } else if ( pfm_mont_is_iear( native_index ) ) { /* O,1 MK */
1419 pfm_bv_set( pd[0].reg_smpl_pmds, 34 );
1420 pfm_bv_set( pd[0].reg_smpl_pmds, 35 );
1421 pfm_bv_set( pd[0].reg_reset_pmds, 34 );
1422 return ( 1 );
1423 }
1424 return ( 0 );
1426 if ( pfm_mont_is_dear( native_index ) ) { /* 2,3,17 */
1427 pfm_bv_set( pd[0].reg_smpl_pmds, 2 );
1428 pfm_bv_set( pd[0].reg_smpl_pmds, 3 );
1429 pfm_bv_set( pd[0].reg_smpl_pmds, 17 );
1430 pfm_bv_set( pd[0].reg_reset_pmds, 17 );
1431 return ( 1 );
1432 } else if ( pfm_mont_is_iear( native_index ) ) { /* O,1 MK */
1433 pfm_bv_set( pd[0].reg_smpl_pmds, 0 );
1434 pfm_bv_set( pd[0].reg_smpl_pmds, 1 );
1435 pfm_bv_set( pd[0].reg_reset_pmds, 0 );
1436 return ( 1 );
1437 }
1438 return ( 0 );
1439 }
1440#else
1441 ( void ) native_index; /*unused */
1442 ( void ) pd; /*unused */
1443#endif
1444 return ( 0 );
1445}
static void pfm_bv_set(uint64_t *bv, uint16_t rnum)
#define PFMLIB_ITANIUM2_PMU
Definition: pfmlib.h:225
#define PFMLIB_MONTECITO_PMU
Definition: pfmlib.h:226
int pfm_mont_is_dear(unsigned int i)
int pfm_mont_is_iear(unsigned int i)
Here is the call graph for this function:
Here is the caller graph for this function:

◆ tune_up_fd()

int tune_up_fd ( int  ctx_fd)

Definition at line 547 of file perfmon2/perfmon.c.

548{
549 int ret;
550
551 /* set close-on-exec to ensure we will be getting the PFM_END_MSG, i.e.,
552 * fd not visible to child. */
553 ret = fcntl( ctx_fd, F_SETFD, FD_CLOEXEC );
554 if ( ret == -1 ) {
555 PAPIERROR( "cannot fcntl(FD_CLOEXEC) on %d: %s", ctx_fd,
556 strerror( errno ) );
557 return ( PAPI_ESYS );
558 }
559 /* setup asynchronous notification on the file descriptor */
560 ret = fcntl( ctx_fd, F_SETFL, fcntl( ctx_fd, F_GETFL, 0 ) | O_ASYNC );
561 if ( ret == -1 ) {
562 PAPIERROR( "cannot fcntl(O_ASYNC) on %d: %s", ctx_fd,
563 strerror( errno ) );
564 return ( PAPI_ESYS );
565 }
566 /* get ownership of the descriptor */
567 ret = fcntl( ctx_fd, F_SETOWN, mygettid( ) );
568 if ( ret == -1 ) {
569 PAPIERROR( "cannot fcntl(F_SETOWN) on %d: %s", ctx_fd,
570 strerror( errno ) );
571 return ( PAPI_ESYS );
572 }
573 /*
574 * when you explicitely declare that you want a particular signal,
575 * even with you use the default signal, the kernel will send more
576 * information concerning the event to the signal handler.
577 *
578 * In particular, it will send the file descriptor from which the
579 * event is originating which can be quite useful when monitoring
580 * multiple tasks from a single thread.
581 */
582 ret = fcntl( ctx_fd, F_SETSIG, _perfmon2_vector.cmp_info.hardware_intr_sig );
583 if ( ret == -1 ) {
584 PAPIERROR( "cannot fcntl(F_SETSIG,%d) on %d: %s",
586 strerror( errno ) );
587 return ( PAPI_ESYS );
588 }
589 return ( PAPI_OK );
590}
Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ _perfmon2_pfm_pmu_type

int _perfmon2_pfm_pmu_type = -1
static

Definition at line 50 of file perfmon2/perfmon.c.

◆ _perfmon2_pfm_unavailable_pmcs

pfmlib_regmask_t _perfmon2_pfm_unavailable_pmcs
static

Definition at line 51 of file perfmon2/perfmon.c.

◆ _perfmon2_pfm_unavailable_pmds

pfmlib_regmask_t _perfmon2_pfm_unavailable_pmds
static

Definition at line 52 of file perfmon2/perfmon.c.

◆ _perfmon2_vector

papi_vector_t _perfmon2_vector

Definition at line 45 of file perfmon2/perfmon.c.