PAPI  5.3.2.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
perfmon.c
Go to the documentation of this file.
1 /*
2 * File: perfmon.c
3 * Author: Philip Mucci
4 * mucci@cs.utk.edu
5 * Mods: Brian Sheely
6 * bsheely@eecs.utk.edu
7 */
8 
9 /* TODO LIST:
10  - Events for all platforms
11  - Derived events for all platforms
12  - Latency profiling
13  - BTB/IPIEAR sampling
14  - Test on ITA2, Pentium 4
15  - hwd_ntv_code_to_name
16  - Make native map carry major events, not umasks
17  - Enum event uses native_map not pfm()
18  - Hook up globals to be freed to sub_info
19  - Better feature bit support for IEAR
20 */
21 
22 #include "papi.h"
23 #include "papi_internal.h"
24 #include "papi_vector.h"
25 #include "papi_memory.h"
26 #include "papi_libpfm_events.h"
27 #include "extras.h"
28 
29 #include "perfmon.h"
30 
31 #include "linux-memory.h"
32 #include "linux-timer.h"
33 #include "linux-common.h"
34 
35 #ifdef __ia64__
36 #include "perfmon/pfmlib_itanium2.h"
37 #include "perfmon/pfmlib_montecito.h"
38 #endif
39 
40 typedef unsigned uint;
41 
42 /* Advance declarations */
43 static int _papi_pfm_set_overflow( EventSetInfo_t * ESI, int EventIndex,
44  int threshold );
46 
47 
48 /* Static locals */
49 
50 static int _perfmon2_pfm_pmu_type = -1;
51 static pfmlib_regmask_t _perfmon2_pfm_unavailable_pmcs;
52 static pfmlib_regmask_t _perfmon2_pfm_unavailable_pmds;
53 
54 /* Debug functions */
55 
56 #ifdef DEBUG
57 static void
58 dump_smpl_arg( pfm_dfl_smpl_arg_t * arg )
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 }
64 
65 static void
66 dump_sets( pfarg_setdesc_t * set, int num_sets )
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 }
80 
81 static void
82 dump_setinfo( pfarg_setinfo_t * setinfo, int num_sets )
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 }
106 
107 static void
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 }
122 
123 static void
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 }
155 
156 static void
157 dump_smpl_hdr( pfm_dfl_smpl_hdr_t * hdr )
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 }
172 
173 static void
174 dump_smpl( pfm_dfl_smpl_entry_t * entry )
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 }
186 #endif
187 
188 #define PFM_MAX_PMCDS 20
189 
190 int
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 }
225 
226 int
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 }
264 
265 int
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 }
300 
301 
302 /* This routine effectively does argument checking as the real magic will happen
303  in compute_kernel_args. This just gets the value back from the kernel. */
304 
305 static int
306 check_multiplex_timeout( int ctx_fd, unsigned long *timeout_ns )
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;
313  set[1].set_flags = PFM_SETFL_TIME_SWITCH;
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 }
338 
339 /* The below function is stolen from libpfm from Stephane Eranian */
340 static int
341 detect_timeout_and_unavail_pmu_regs( pfmlib_regmask_t * r_pmcs,
342  pfmlib_regmask_t * r_pmds,
343  unsigned long *timeout_ns )
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 }
396 
397 /* BEGIN COMMON CODE */
398 
399 static inline int
401 {
402  pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
403  pfmlib_input_param_t *inp = &ctl->in;
404  pfmlib_output_param_t *outp = &ctl->out;
405  pfmlib_input_param_t tmpin;
406  pfmlib_output_param_t tmpout;
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",
428  ctl->multiplexed, inp->pfp_event_count, _perfmon2_vector.cmp_info.num_cntrs,
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 */
447  memcpy( &tmpin.pfp_unavail_pmcs, &_perfmon2_pfm_unavailable_pmcs,
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;
521  if ( togo > _perfmon2_vector.cmp_info.num_cntrs )
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++ ) {
536  sets[i].set_flags = PFM_SETFL_TIME_SWITCH;
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 }
545 
546 int
547 tune_up_fd( int ctx_fd )
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",
585  _perfmon2_vector.cmp_info.hardware_intr_sig, ctx_fd,
586  strerror( errno ) );
587  return ( PAPI_ESYS );
588  }
589  return ( PAPI_OK );
590 }
591 
592 static int
593 attach( hwd_control_state_t * ctl, unsigned long tid )
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 }
643 
644 static int
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 }
665 
666 static inline int
667 set_domain( hwd_control_state_t * ctl0, int domain )
668 {
669  pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
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 }
700 
701 static inline int
702 set_granularity( hwd_control_state_t * this_state, int domain )
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 }
718 
719 /* This function should tell your kernel extension that your children
720  inherit performance register information and propagate the values up
721  upon child exit and parent wait. */
722 
723 static inline int
724 set_inherit( int arg )
725 {
726  ( void ) arg; /*unused */
727  return PAPI_ECMP;
728 }
729 
730 static int
731 get_string_from_file( char *file, char *str, int len )
732 {
733  FILE *f = fopen( file, "r" );
734  char buf[PAPI_HUGE_STR_LEN];
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 }
748 
749 int
751 {
752  int retval;
753  char buf[PAPI_HUGE_STR_LEN];
754 
755  /* The following checks the PFMLIB version
756  against the perfmon2 kernel version... */
757  strncpy( _perfmon2_vector.cmp_info.support_version, buf,
758  sizeof ( _perfmon2_vector.cmp_info.support_version ) );
759 
760  retval = get_string_from_file( "/sys/kernel/perfmon/version",
761  _perfmon2_vector.cmp_info.kernel_version,
762  sizeof ( _perfmon2_vector.cmp_info.kernel_version ) );
763  if ( retval != PAPI_OK ) {
764  strncpy(_perfmon2_vector.cmp_info.disabled_reason,
765  "/sys/kernel/perfmon/version not found",PAPI_MAX_STR_LEN);
766  return retval;
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",
773  _perfmon2_vector.cmp_info.kernel_version, buf );
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",
781  buf, _perfmon2_vector.cmp_info.kernel_version );
782  return PAPI_ESYS;
783  }
784  }
785 #endif
786 
787  _perfmon2_vector.cmp_info.hardware_intr_sig = SIGRTMIN + 2,
788 
789 
790  /* Run the libpfm-specific setup */
791  retval=_papi_libpfm_init(&_perfmon2_vector, cidx);
792  if (retval) return retval;
793 
794  /* Load the module, find out if any PMC's/PMD's are off limits */
795 
796  /* Perfmon2 timeouts are based on the clock tick, we need to check
797  them otherwise it will complain at us when we multiplex */
798 
799  unsigned long min_timeout_ns;
800 
801  struct timespec ts;
802 
803  if ( syscall( __NR_clock_getres, CLOCK_REALTIME, &ts ) == -1 ) {
804  PAPIERROR( "Could not detect proper HZ rate, multiplexing may fail\n" );
805  min_timeout_ns = 10000000;
806  } else {
807  min_timeout_ns = ts.tv_nsec;
808  }
809 
810  /* This will fail if we've done timeout detection wrong */
813  &min_timeout_ns );
814  if ( retval != PAPI_OK ) {
815  return ( retval );
816  }
817 
819  /* powerpc */
820  _perfmon2_vector.cmp_info.available_domains |= PAPI_DOM_KERNEL |
822  if (strcmp(_papi_hwi_system_info.hw_info.model_string, "POWER6" ) == 0) {
823  _perfmon2_vector.cmp_info.default_domain = PAPI_DOM_USER |
824  PAPI_DOM_KERNEL |
826  }
827  } else {
828  _perfmon2_vector.cmp_info.available_domains |= PAPI_DOM_KERNEL;
829  }
830 
832  switch ( _perfmon2_pfm_pmu_type ) {
833 #ifdef PFMLIB_SPARC_ULTRA12_PMU
834  case PFMLIB_SPARC_ULTRA12_PMU:
835  case PFMLIB_SPARC_ULTRA3_PMU:
836  case PFMLIB_SPARC_ULTRA3I_PMU:
837  case PFMLIB_SPARC_ULTRA3PLUS_PMU:
838  case PFMLIB_SPARC_ULTRA4PLUS_PMU:
839  break;
840 #endif
841  default:
842  _perfmon2_vector.cmp_info.available_domains |=
844  break;
845  }
846  }
847 
849  _perfmon2_vector.cmp_info.available_domains |= PAPI_DOM_OTHER;
850  }
851 
854  _perfmon2_vector.cmp_info.fast_counter_read = 1;
855  _perfmon2_vector.cmp_info.fast_real_timer = 1;
856  _perfmon2_vector.cmp_info.cntr_umasks = 1;
857  }
858 
859  return PAPI_OK;
860 }
861 
862 int
864 {
865  return PAPI_OK;
866 }
867 
868 static int
870 {
871  pfarg_load_t load_args;
872  pfarg_ctx_t newctx;
873  int ret, ctx_fd;
874 
875 #if defined(USE_PROC_PTTIMER)
876  ret = init_proc_thread_timer( thr_ctx );
877  if ( ret != PAPI_OK )
878  return ( ret );
879 #endif
880 
881  memset( &newctx, 0, sizeof ( newctx ) );
882  memset( &load_args, 0, sizeof ( load_args ) );
883 
884  if ( ( ret = pfm_create_context( &newctx, NULL, NULL, 0 ) ) == -1 ) {
885  PAPIERROR( "pfm_create_context(): %s",
886  strerror( errno ) );
887  return ( PAPI_ESYS );
888  }
889  SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", ret );
890  tune_up_fd( ret );
891  ctx_fd = ret;
892 
893  memcpy( &( ( pfm_context_t * ) thr_ctx )->ctx, &newctx, sizeof ( newctx ) );
894  ( ( pfm_context_t * ) thr_ctx )->ctx_fd = ctx_fd;
895  load_args.load_pid = mygettid( );
896  memcpy( &( ( pfm_context_t * ) thr_ctx )->load, &load_args,
897  sizeof ( load_args ) );
898 
899  return ( PAPI_OK );
900 }
901 
902 /* reset the hardware counters */
903 int
905 {
906  unsigned int i;
907  int ret;
908 
909  /* Read could have clobbered the values */
910  for ( i = 0; i < ( ( pfm_control_state_t * ) ctl )->in.pfp_event_count;
911  i++ ) {
912  if ( ( ( pfm_control_state_t * ) ctl )->pd[i].
913  reg_flags & PFM_REGFL_OVFL_NOTIFY )
914  ( ( pfm_control_state_t * ) ctl )->pd[i].reg_value =
915  ( ( pfm_control_state_t * ) ctl )->pd[i].reg_long_reset;
916  else
917  ( ( pfm_control_state_t * ) ctl )->pd[i].reg_value = 0ULL;
918  }
919 
920  ret =
922  ( pfm_control_state_t * ) ctl );
923  if ( ret != PAPI_OK )
924  return PAPI_ESYS;
925 
926  return ( PAPI_OK );
927 }
928 
929 /* write(set) the hardware counters */
930 int
932  long long *from )
933 {
934  unsigned int i;
935  int ret;
936 
937  /* Read could have clobbered the values */
938  for ( i = 0; i < ( ( pfm_control_state_t * ) ctl )->in.pfp_event_count;
939  i++ ) {
940  if ( ( ( pfm_control_state_t * ) ctl )->pd[i].
941  reg_flags & PFM_REGFL_OVFL_NOTIFY )
942  ( ( pfm_control_state_t * ) ctl )->pd[i].reg_value =
943  from[i] +
944  ( ( pfm_control_state_t * ) ctl )->pd[i].reg_long_reset;
945  else
946  ( ( pfm_control_state_t * ) ctl )->pd[i].reg_value = from[i];
947  }
948 
949  ret =
951  ( pfm_control_state_t * ) ctl );
952  if ( ret != PAPI_OK )
953  return PAPI_ESYS;
954 
955 
956  return ( PAPI_OK );
957 }
958 
959 int
961  long long **events, int flags )
962 {
963  ( void ) flags; /*unused */
964  unsigned int i;
965  int ret;
966  long long tot_runs = 0LL;
967  pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
968  pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
969 
970  ret = _papi_pfm_read_pmds( ctx, ctl );
971  if ( ret != PAPI_OK )
972  return PAPI_ESYS;
973 
974  /* Copy the values over */
975 
976  for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
977  if ( ctl->pd[i].reg_flags & PFM_REGFL_OVFL_NOTIFY )
978  ctl->counts[i] = ctl->pd[i].reg_value - ctl->pd[i].reg_long_reset;
979  else
980  ctl->counts[i] = ctl->pd[i].reg_value;
981  SUBDBG( "PMD[%d] = %lld (LLD),%llu (LLU)\n", i,
982  ( unsigned long long ) ctl->counts[i],
983  ( unsigned long long ) ctl->pd[i].reg_value );
984  }
985  *events = ctl->counts;
986 
987  /* If we're not multiplexing, bail now */
988 
989  if ( ctl->num_sets == 1 )
990  return ( PAPI_OK );
991 
992  /* If we're multiplexing, get the scaling information */
993 
994  SUBDBG( "PFM_GETINFO_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, ctl->setinfo,
995  ctl->num_sets );
996  if ( ( ret =
997  pfm_getinfo_evtsets( ctl->ctx_fd, ctl->setinfo, ctl->num_sets ) ) ) {
999  dump_setinfo( ctl->setinfo, ctl->num_sets ) );
1000  PAPIERROR( "pfm_getinfo_evtsets(%d,%p,%d): %s", ctl->ctx_fd,
1001  ctl->setinfo, ctl->num_sets, strerror( ret ) );
1002  *events = NULL;
1003  return ( PAPI_ESYS );
1004  }
1006 
1007  /* Add up the number of total runs */
1008 
1009  for ( i = 0; i < ( unsigned int ) ctl->num_sets; i++ )
1010  tot_runs += ctl->setinfo[i].set_runs;
1011 
1012  /* Now scale the values */
1013 
1014  for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
1015  SUBDBG
1016  ( "Counter %d is in set %d ran %llu of %llu times, old count %lld.\n",
1017  i, ctl->pd[i].reg_set,
1018  ( unsigned long long ) ctl->setinfo[ctl->pd[i].reg_set].set_runs,
1019  ( unsigned long long ) tot_runs, ctl->counts[i] );
1020  if ( ctl->setinfo[ctl->pd[i].reg_set].set_runs )
1021  ctl->counts[i] =
1022  ( ctl->counts[i] * tot_runs ) /
1023  ctl->setinfo[ctl->pd[i].reg_set].set_runs;
1024  else {
1025  ctl->counts[i] = 0;
1026  SUBDBG( "Set %lld didn't run!!!!\n",
1027  ( unsigned long long ) ctl->pd[i].reg_set );
1028  }
1029  SUBDBG( "Counter %d, new count %lld.\n", i, ctl->counts[i] );
1030  }
1031 
1032  return PAPI_OK;
1033 }
1034 
1035 #if defined(__crayxt)
1036 int _papi_hwd_start_create_context = 0; /* CrayPat checkpoint support */
1037 #endif /* XT */
1038 
1039 int
1041 {
1042  unsigned int i;
1043  int ret;
1044  pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
1045  pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
1046 
1047 #if defined(__crayxt)
1048  if ( _papi_hwd_start_create_context ) {
1049  pfarg_ctx_t tmp;
1050 
1051  memset( &tmp, 0, sizeof ( tmp ) );
1052  if ( ( ret = pfm_create_context( &tmp, NULL, NULL, 0 ) ) == -1 ) {
1053  PAPIERROR( "_papi_hwd_init:pfm_create_context(): %s",
1054  strerror( errno ) );
1055  return ( PAPI_ESYS );
1056  }
1057  tune_up_fd( ret );
1058  ctl->ctx_fd = ctx->ctx_fd = ret;
1059  }
1060 #endif /* XT */
1061 
1062  if ( ctl->num_sets > 1 ) {
1063  SUBDBG( "PFM_CREATE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, ctl->set,
1064  ctl->num_sets );
1065  if ( ( ret =
1066  pfm_create_evtsets( ctl->ctx_fd, ctl->set,
1067  ctl->num_sets ) ) != PFMLIB_SUCCESS ) {
1068  DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( ctl->set, ctl->num_sets ) );
1069  PAPIERROR( "pfm_create_evtsets(%d,%p,%d): errno=%d %s",
1070  ctl->ctx_fd, ctl->set, ctl->num_sets, errno,
1071  strerror( ret ) );
1072  perror( "pfm_create_evtsets" );
1073  return ( PAPI_ESYS );
1074  }
1075  DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( ctl->set, ctl->num_sets ) );
1076  }
1077 
1078  /*
1079  * Now program the registers
1080  *
1081  * We don't use the same variable to indicate the number of elements passed to
1082  * the kernel because, as we said earlier, pc may contain more elements than
1083  * the number of events (pmd) we specified, i.e., contains more than counting
1084  * monitors.
1085  */
1086 
1087  ret = _papi_pfm_write_pmcs( ctx, ctl );
1088  if ( ret != PAPI_OK )
1089  return PAPI_ESYS;
1090 
1091  /* Set counters to zero as per PAPI_start man page, unless it is set to overflow */
1092 
1093  for ( i = 0; i < ctl->in.pfp_event_count; i++ )
1094  if ( !( ctl->pd[i].reg_flags & PFM_REGFL_OVFL_NOTIFY ) )
1095  ctl->pd[i].reg_value = 0ULL;
1096 
1097  /*
1098  * To be read, each PMD must be either written or declared
1099  * as being part of a sample (reg_smpl_pmds)
1100  */
1101 
1102  ret = _papi_pfm_write_pmds( ctx, ctl );
1103  if ( ret != PAPI_OK )
1104  return PAPI_ESYS;
1105 
1106  SUBDBG( "PFM_LOAD_CONTEXT(%d,%p(%u))\n", ctl->ctx_fd, ctl->load,
1107  ctl->load->load_pid );
1108  if ( ( ret = pfm_load_context( ctl->ctx_fd, ctl->load ) ) ) {
1109  PAPIERROR( "pfm_load_context(%d,%p(%u)): %s", ctl->ctx_fd, ctl->load,
1110  ctl->load->load_pid, strerror( ret ) );
1111  return PAPI_ESYS;
1112  }
1113 
1114  SUBDBG( "PFM_START(%d,%p)\n", ctl->ctx_fd, NULL );
1115  if ( ( ret = pfm_start( ctl->ctx_fd, NULL ) ) ) {
1116  PAPIERROR( "pfm_start(%d): %s", ctl->ctx_fd, strerror( ret ) );
1117  return ( PAPI_ESYS );
1118  }
1119  return PAPI_OK;
1120 }
1121 
1122 int
1124 {
1125  ( void ) ctx0; /*unused */
1126  int ret;
1127  pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
1128 // pfm_context_t *ctx = (pfm_context_t *)ctx0;
1129 
1130  SUBDBG( "PFM_STOP(%d)\n", ctl->ctx_fd );
1131  if ( ( ret = pfm_stop( ctl->ctx_fd ) ) ) {
1132  /* If this thread is attached to another thread, and that thread
1133  has exited, we can safely discard the error here. */
1134 
1135  if ( ( ret == PFMLIB_ERR_NOTSUPP ) &&
1136  ( ctl->load->load_pid != ( unsigned int ) mygettid( ) ) )
1137  return ( PAPI_OK );
1138 
1139  PAPIERROR( "pfm_stop(%d): %s", ctl->ctx_fd, strerror( ret ) );
1140  return ( PAPI_ESYS );
1141  }
1142 
1143  SUBDBG( "PFM_UNLOAD_CONTEXT(%d) (tid %u)\n", ctl->ctx_fd,
1144  ctl->load->load_pid );
1145  if ( ( ret = pfm_unload_context( ctl->ctx_fd ) ) ) {
1146  PAPIERROR( "pfm_unload_context(%d): %s", ctl->ctx_fd, strerror( ret ) );
1147  return PAPI_ESYS;
1148  }
1149 
1150  if ( ctl->num_sets > 1 ) {
1151  static pfarg_setdesc_t set = { 0, 0, 0, 0, {0, 0, 0, 0, 0, 0} };
1152  /* Delete the high sets */
1153  SUBDBG( "PFM_DELETE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, &ctl->set[1],
1154  ctl->num_sets - 1 );
1155  if ( ( ret =
1156  pfm_delete_evtsets( ctl->ctx_fd, &ctl->set[1],
1157  ctl->num_sets - 1 ) ) != PFMLIB_SUCCESS ) {
1159  dump_sets( &ctl->set[1], ctl->num_sets - 1 ) );
1160  PAPIERROR( "pfm_delete_evtsets(%d,%p,%d): %s", ctl->ctx_fd,
1161  &ctl->set[1], ctl->num_sets - 1, strerror( ret ) );
1162  return ( PAPI_ESYS );
1163  }
1165  dump_sets( &ctl->set[1], ctl->num_sets - 1 ) );
1166  /* Reprogram the 0 set */
1167  SUBDBG( "PFM_CREATE_EVTSETS(%d,%p,%d)\n", ctl->ctx_fd, &set, 1 );
1168  if ( ( ret =
1169  pfm_create_evtsets( ctl->ctx_fd, &set,
1170  1 ) ) != PFMLIB_SUCCESS ) {
1171  DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( &set, 1 ) );
1172  PAPIERROR( "pfm_create_evtsets(%d,%p,%d): %s", ctl->ctx_fd, &set,
1173  ctl->num_sets, strerror( ret ) );
1174  return ( PAPI_ESYS );
1175  }
1176  DEBUGCALL( DEBUG_SUBSTRATE, dump_sets( &set, 1 ) );
1177  }
1178 
1179  return PAPI_OK;
1180 }
1181 
1182 static inline int
1184 {
1185  if ( ns <= _papi_os_info.itimer_res_ns ) {
1187  } else {
1188  int leftover_ns = ns % _papi_os_info.itimer_res_ns;
1189  return ( ns - leftover_ns + _papi_os_info.itimer_res_ns );
1190  }
1191 }
1192 
1193 int
1194 _papi_pfm_ctl( hwd_context_t * ctx, int code, _papi_int_option_t * option )
1195 {
1196  switch ( code ) {
1197  case PAPI_MULTIPLEX:
1198  {
1199  option->multiplex.ns = round_requested_ns( option->multiplex.ns );
1200  ( ( pfm_control_state_t * ) ( option->multiplex.ESI->ctl_state ) )->
1201  multiplexed = option->multiplex.ns;
1202  return ( PAPI_OK );
1203  }
1204 
1205  case PAPI_ATTACH:
1206  return ( attach
1207  ( ( pfm_control_state_t * ) ( option->attach.ESI->ctl_state ),
1208  option->attach.tid ) );
1209  case PAPI_DETACH:
1210  return ( detach
1211  ( ctx,
1212  ( pfm_control_state_t * ) ( option->attach.ESI->
1213  ctl_state ) ) );
1214 
1215  case PAPI_DOMAIN:
1216  return ( set_domain
1217  ( ( pfm_control_state_t * ) ( option->domain.ESI->ctl_state ),
1218  option->domain.domain ) );
1219  case PAPI_GRANUL:
1220  return ( set_granularity
1221  ( ( pfm_control_state_t * ) ( option->granularity.ESI->
1222  ctl_state ),
1223  option->granularity.granularity ) );
1224 #if 0
1225  case PAPI_DATA_ADDRESS:
1226  ret =
1227  set_default_domain( ( pfm_control_state_t * ) ( option->
1228  address_range.ESI->
1229  ctl_state ),
1230  option->address_range.domain );
1231  if ( ret != PAPI_OK )
1232  return ( ret );
1233  set_drange( ctx,
1234  ( pfm_control_state_t * ) ( option->address_range.ESI->
1235  ctl_state ), option );
1236  return ( PAPI_OK );
1237  case PAPI_INSTR_ADDRESS:
1238  ret =
1239  set_default_domain( ( pfm_control_state_t * ) ( option->
1240  address_range.ESI->
1241  ctl_state ),
1242  option->address_range.domain );
1243  if ( ret != PAPI_OK )
1244  return ( ret );
1245  set_irange( ctx,
1246  ( pfm_control_state_t * ) ( option->address_range.ESI->
1247  ctl_state ), option );
1248  return ( PAPI_OK );
1249 #endif
1250 
1251 
1252  case PAPI_DEF_ITIMER:
1253  {
1254  /* flags are currently ignored, eventually the flags will be able
1255  to specify whether or not we use POSIX itimers (clock_gettimer) */
1256  if ( ( option->itimer.itimer_num == ITIMER_REAL ) &&
1257  ( option->itimer.itimer_sig != SIGALRM ) )
1258  return PAPI_EINVAL;
1259  if ( ( option->itimer.itimer_num == ITIMER_VIRTUAL ) &&
1260  ( option->itimer.itimer_sig != SIGVTALRM ) )
1261  return PAPI_EINVAL;
1262  if ( ( option->itimer.itimer_num == ITIMER_PROF ) &&
1263  ( option->itimer.itimer_sig != SIGPROF ) )
1264  return PAPI_EINVAL;
1265  if ( option->itimer.ns > 0 )
1266  option->itimer.ns = round_requested_ns( option->itimer.ns );
1267  /* At this point, we assume the user knows what he or
1268  she is doing, they maybe doing something arch specific */
1269  return PAPI_OK;
1270  }
1271 
1272  case PAPI_DEF_MPX_NS:
1273  {
1274  option->multiplex.ns = round_requested_ns( option->multiplex.ns );
1275  return ( PAPI_OK );
1276  }
1277  case PAPI_DEF_ITIMER_NS:
1278  {
1279  option->itimer.ns = round_requested_ns( option->itimer.ns );
1280  return ( PAPI_OK );
1281  }
1282  default:
1283  return ( PAPI_ENOSUPP );
1284  }
1285 }
1286 
1287 int
1289 {
1290  pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
1291  int ret;
1292 #if defined(USE_PROC_PTTIMER)
1293  close( ctx->stat_fd );
1294 #endif
1295 
1296 
1297  ret = close( ctx->ctx_fd );
1298  SUBDBG( "CLOSE fd %d returned %d\n", ctx->ctx_fd, ret );
1299  (void) ret;
1300 
1301  return ( PAPI_OK );
1302 }
1303 
1304 /* This will need to be modified for the Pentium IV */
1305 
1306 static inline int
1308  unsigned int *native_index, int *profile_index )
1309 {
1310  int pos, esi_index, count;
1312  pfarg_pmd_t *pd;
1313  unsigned int i;
1314 
1315  pd = ctl->pd;
1316 
1317  /* Find virtual PMD index, the one we actually read from the physical PMD number that
1318  overflowed. This index is the one related to the profile buffer. */
1319 
1320  for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
1321  if ( pd[i].reg_num == pmd ) {
1322  SUBDBG( "Physical PMD %d is Virtual PMD %d\n", pmd, i );
1323  pmd = i;
1324  break;
1325  }
1326  }
1327 
1328 
1329  SUBDBG( "(%p,%d,%p)\n", ESI, pmd, index );
1330 
1331  for ( count = 0; count < ESI->profile.event_counter; count++ ) {
1332  /* Find offset of PMD that gets read from the kernel */
1333  esi_index = ESI->profile.EventIndex[count];
1334  pos = ESI->EventInfoArray[esi_index].pos[0];
1335  SUBDBG( "Examining event at ESI index %d, PMD position %d\n", esi_index,
1336  pos );
1337  // PMU_FIRST_COUNTER
1338  if ( pos == pmd ) {
1339  *profile_index = count;
1340  *native_index =
1342  *flags = ESI->profile.flags;
1343  SUBDBG( "Native event %d is at profile index %d, flags %d\n",
1344  *native_index, *profile_index, *flags );
1345  return ( PAPI_OK );
1346  }
1347  }
1348 
1349  PAPIERROR( "wrong count: %d vs. ESI->profile.event_counter %d", count,
1350  ESI->profile.event_counter );
1351  return ( PAPI_EBUG );
1352 }
1353 
1354 #if defined(__ia64__)
1355 static inline int
1356 is_montecito_and_dear( unsigned int native_index )
1357 {
1358  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU ) {
1359  if ( pfm_mont_is_dear( native_index ) )
1360  return ( 1 );
1361  }
1362  return ( 0 );
1363 }
1364 static inline int
1365 is_montecito_and_iear( unsigned int native_index )
1366 {
1367  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU ) {
1368  if ( pfm_mont_is_iear( native_index ) )
1369  return ( 1 );
1370  }
1371  return ( 0 );
1372 }
1373 static inline int
1374 is_itanium2_and_dear( unsigned int native_index )
1375 {
1376  if ( _perfmon2_pfm_pmu_type == PFMLIB_ITANIUM2_PMU ) {
1377  if ( pfm_ita2_is_dear( native_index ) )
1378  return ( 1 );
1379  }
1380  return ( 0 );
1381 }
1382 static inline int
1383 is_itanium2_and_iear( unsigned int native_index )
1384 {
1385  if ( _perfmon2_pfm_pmu_type == PFMLIB_ITANIUM2_PMU ) {
1386  if ( pfm_ita2_is_iear( native_index ) )
1387  return ( 1 );
1388  }
1389  return ( 0 );
1390 }
1391 #endif
1392 
1393 #define BPL (sizeof(uint64_t)<<3)
1394 #define LBPL 6
1395 static inline void
1396 pfm_bv_set( uint64_t * bv, uint16_t rnum )
1397 {
1398  bv[rnum >> LBPL] |= 1UL << ( rnum & ( BPL - 1 ) );
1399 }
1400 
1401 static inline int
1402 setup_ear_event( unsigned int native_index, pfarg_pmd_t * pd, int flags )
1403 {
1404  ( void ) flags; /*unused */
1405 #if defined(__ia64__)
1406  if ( _perfmon2_pfm_pmu_type == PFMLIB_MONTECITO_PMU ) {
1407  if ( pfm_mont_is_dear( native_index ) ) { /* 2,3,17 */
1408  pfm_bv_set( pd[0].reg_smpl_pmds, 32 );
1409  pfm_bv_set( pd[0].reg_smpl_pmds, 33 );
1410  pfm_bv_set( pd[0].reg_smpl_pmds, 36 );
1411  pfm_bv_set( pd[0].reg_reset_pmds, 36 );
1412  return ( 1 );
1413  } else if ( pfm_mont_is_iear( native_index ) ) { /* O,1 MK */
1414  pfm_bv_set( pd[0].reg_smpl_pmds, 34 );
1415  pfm_bv_set( pd[0].reg_smpl_pmds, 35 );
1416  pfm_bv_set( pd[0].reg_reset_pmds, 34 );
1417  return ( 1 );
1418  }
1419  return ( 0 );
1420  } else if ( _perfmon2_pfm_pmu_type == PFMLIB_ITANIUM2_PMU ) {
1421  if ( pfm_mont_is_dear( native_index ) ) { /* 2,3,17 */
1422  pfm_bv_set( pd[0].reg_smpl_pmds, 2 );
1423  pfm_bv_set( pd[0].reg_smpl_pmds, 3 );
1424  pfm_bv_set( pd[0].reg_smpl_pmds, 17 );
1425  pfm_bv_set( pd[0].reg_reset_pmds, 17 );
1426  return ( 1 );
1427  } else if ( pfm_mont_is_iear( native_index ) ) { /* O,1 MK */
1428  pfm_bv_set( pd[0].reg_smpl_pmds, 0 );
1429  pfm_bv_set( pd[0].reg_smpl_pmds, 1 );
1430  pfm_bv_set( pd[0].reg_reset_pmds, 0 );
1431  return ( 1 );
1432  }
1433  return ( 0 );
1434  }
1435 #else
1436  ( void ) native_index; /*unused */
1437  ( void ) pd; /*unused */
1438 #endif
1439  return ( 0 );
1440 }
1441 
1442 static inline int
1443 process_smpl_entry( unsigned int native_pfm_index, int flags,
1444  pfm_dfl_smpl_entry_t ** ent, caddr_t * pc )
1445 {
1446 #ifndef __ia64__
1447  ( void ) native_pfm_index; /*unused */
1448  ( void ) flags; /*unused */
1449 #endif
1450  SUBDBG( "process_smpl_entry(%d,%d,%p,%p)\n", native_pfm_index, flags, ent,
1451  pc );
1452 
1453 #ifdef __ia64__
1454  /* Fixup EAR stuff here */
1455  if ( is_montecito_and_dear( native_pfm_index ) ) {
1456  pfm_mont_pmd_reg_t data_addr;
1457  pfm_mont_pmd_reg_t latency;
1458  pfm_mont_pmd_reg_t load_addr;
1459  unsigned long newent;
1460 
1461  if ( ( flags & ( PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR ) ) == 0 )
1462  goto safety;
1463 
1464  /* Skip the header */
1465  ++( *ent );
1466 
1467  // PMD32 has data address on Montecito
1468  // PMD33 has latency on Montecito
1469  // PMD36 has instruction address on Montecito
1470  data_addr = *( pfm_mont_pmd_reg_t * ) * ent;
1471  latency =
1472  *( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
1473  sizeof ( data_addr ) );
1474  load_addr =
1475  *( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
1476  sizeof ( data_addr ) +
1477  sizeof ( latency ) );
1478 
1479  SUBDBG( "PMD[32]: %#016llx\n",
1480  ( unsigned long long ) data_addr.pmd_val );
1481  SUBDBG( "PMD[33]: %#016llx\n",
1482  ( unsigned long long ) latency.pmd_val );
1483  SUBDBG( "PMD[36]: %#016llx\n",
1484  ( unsigned long long ) load_addr.pmd_val );
1485 
1486  if ( ( !load_addr.pmd36_mont_reg.dear_vl ) ||
1487  ( !load_addr.pmd33_mont_reg.dear_stat ) ) {
1488  SUBDBG
1489  ( "Invalid DEAR sample found, dear_vl = %d, dear_stat = %#x\n",
1490  load_addr.pmd36_mont_reg.dear_vl,
1491  load_addr.pmd33_mont_reg.dear_stat );
1492  bail1:
1493  newent = ( unsigned long ) *ent;
1494  newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
1495  *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1496  return 0;
1497  }
1498 
1499  if ( flags & PAPI_PROFIL_DATA_EAR )
1500  *pc = ( caddr_t ) data_addr.pmd_val;
1501  else if ( flags & PAPI_PROFIL_INST_EAR ) {
1502  unsigned long tmp =
1503  ( ( load_addr.pmd36_mont_reg.dear_iaddr +
1504  ( unsigned long ) load_addr.pmd36_mont_reg.
1505  dear_bn ) << 4 ) | ( unsigned long ) load_addr.
1506  pmd36_mont_reg.dear_slot;
1507  *pc = ( caddr_t ) tmp;
1508  } else {
1509  PAPIERROR( "BUG!" );
1510  goto bail1;
1511  }
1512 
1513  newent = ( unsigned long ) *ent;
1514  newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
1515  *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1516  return 0;
1517  } else if ( is_montecito_and_iear( native_pfm_index ) ) {
1518  pfm_mont_pmd_reg_t latency;
1519  pfm_mont_pmd_reg_t icache_line_addr;
1520  unsigned long newent;
1521 
1522  if ( ( flags & PAPI_PROFIL_INST_EAR ) == 0 )
1523  goto safety;
1524 
1525  /* Skip the header */
1526  ++( *ent );
1527 
1528  // PMD34 has data address on Montecito
1529  // PMD35 has latency on Montecito
1530  icache_line_addr = *( pfm_mont_pmd_reg_t * ) * ent;
1531  latency =
1532  *( pfm_mont_pmd_reg_t * ) ( ( unsigned long ) *ent +
1533  sizeof ( icache_line_addr ) );
1534 
1535  SUBDBG( "PMD[34]: %#016llx\n",
1536  ( unsigned long long ) icache_line_addr.pmd_val );
1537  SUBDBG( "PMD[35]: %#016llx\n",
1538  ( unsigned long long ) latency.pmd_val );
1539 
1540  if ( ( icache_line_addr.pmd34_mont_reg.iear_stat & 0x1 ) == 0 ) {
1541  SUBDBG( "Invalid IEAR sample found, iear_stat = %#x\n",
1542  icache_line_addr.pmd34_mont_reg.iear_stat );
1543  bail2:
1544  newent = ( unsigned long ) *ent;
1545  newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
1546  *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1547  return ( 0 );
1548  }
1549 
1550  if ( flags & PAPI_PROFIL_INST_EAR ) {
1551  unsigned long tmp = icache_line_addr.pmd34_mont_reg.iear_iaddr << 5;
1552  *pc = ( caddr_t ) tmp;
1553  } else {
1554  PAPIERROR( "BUG!" );
1555  goto bail2;
1556  }
1557 
1558  newent = ( unsigned long ) *ent;
1559  newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
1560  *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1561  return 0;
1562  } else if ( is_itanium2_and_dear( native_pfm_index ) ) {
1563  pfm_ita2_pmd_reg_t data_addr;
1564  pfm_ita2_pmd_reg_t latency;
1565  pfm_ita2_pmd_reg_t load_addr;
1566  unsigned long newent;
1567 
1568  if ( ( flags & ( PAPI_PROFIL_DATA_EAR | PAPI_PROFIL_INST_EAR ) ) == 0 )
1569  goto safety;
1570 
1571  /* Skip the header */
1572  ++( *ent );
1573 
1574  // PMD2 has data address on Itanium 2
1575  // PMD3 has latency on Itanium 2
1576  // PMD17 has instruction address on Itanium 2
1577  data_addr = *( pfm_ita2_pmd_reg_t * ) * ent;
1578  latency =
1579  *( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
1580  sizeof ( data_addr ) );
1581  load_addr =
1582  *( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
1583  sizeof ( data_addr ) +
1584  sizeof ( latency ) );
1585 
1586  SUBDBG( "PMD[2]: %#016llx\n",
1587  ( unsigned long long ) data_addr.pmd_val );
1588  SUBDBG( "PMD[3]: %#016llx\n", ( unsigned long long ) latency.pmd_val );
1589  SUBDBG( "PMD[17]: %#016llx\n",
1590  ( unsigned long long ) load_addr.pmd_val );
1591 
1592  if ( ( !load_addr.pmd17_ita2_reg.dear_vl ) ||
1593  ( !load_addr.pmd3_ita2_reg.dear_stat ) ) {
1594  SUBDBG
1595  ( "Invalid DEAR sample found, dear_vl = %d, dear_stat = %#x\n",
1596  load_addr.pmd17_ita2_reg.dear_vl,
1597  load_addr.pmd3_ita2_reg.dear_stat );
1598  bail3:
1599  newent = ( unsigned long ) *ent;
1600  newent += 3 * sizeof ( pfm_mont_pmd_reg_t );
1601  *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1602  return 0;
1603  }
1604 
1605  if ( flags & PAPI_PROFIL_DATA_EAR )
1606  *pc = ( caddr_t ) data_addr.pmd_val;
1607  else if ( flags & PAPI_PROFIL_INST_EAR ) {
1608  unsigned long tmp =
1609  ( ( load_addr.pmd17_ita2_reg.dear_iaddr +
1610  ( unsigned long ) load_addr.pmd17_ita2_reg.
1611  dear_bn ) << 4 ) | ( unsigned long ) load_addr.
1612  pmd17_ita2_reg.dear_slot;
1613  *pc = ( caddr_t ) tmp;
1614  } else {
1615  PAPIERROR( "BUG!" );
1616  goto bail3;
1617  }
1618 
1619  newent = ( unsigned long ) *ent;
1620  newent += 3 * sizeof ( pfm_ita2_pmd_reg_t );
1621  *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1622  return 0;
1623  } else if ( is_itanium2_and_iear( native_pfm_index ) ) {
1624  pfm_ita2_pmd_reg_t latency;
1625  pfm_ita2_pmd_reg_t icache_line_addr;
1626  unsigned long newent;
1627 
1628  if ( ( flags & PAPI_PROFIL_INST_EAR ) == 0 )
1629  goto safety;
1630 
1631  /* Skip the header */
1632  ++( *ent );
1633 
1634  // PMD0 has address on Itanium 2
1635  // PMD1 has latency on Itanium 2
1636  icache_line_addr = *( pfm_ita2_pmd_reg_t * ) * ent;
1637  latency =
1638  *( pfm_ita2_pmd_reg_t * ) ( ( unsigned long ) *ent +
1639  sizeof ( icache_line_addr ) );
1640 
1641  SUBDBG( "PMD[0]: %#016llx\n",
1642  ( unsigned long long ) icache_line_addr.pmd_val );
1643  SUBDBG( "PMD[1]: %#016llx\n", ( unsigned long long ) latency.pmd_val );
1644 
1645  if ( ( icache_line_addr.pmd0_ita2_reg.iear_stat & 0x1 ) == 0 ) {
1646  SUBDBG( "Invalid IEAR sample found, iear_stat = %#x\n",
1647  icache_line_addr.pmd0_ita2_reg.iear_stat );
1648  bail4:
1649  newent = ( unsigned long ) *ent;
1650  newent += 2 * sizeof ( pfm_mont_pmd_reg_t );
1651  *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1652  return ( 0 );
1653  }
1654 
1655  if ( flags & PAPI_PROFIL_INST_EAR ) {
1656  unsigned long tmp = icache_line_addr.pmd0_ita2_reg.iear_iaddr << 5;
1657  *pc = ( caddr_t ) tmp;
1658  } else {
1659  PAPIERROR( "BUG!" );
1660  goto bail4;
1661  }
1662 
1663  newent = ( unsigned long ) *ent;
1664  newent += 2 * sizeof ( pfm_ita2_pmd_reg_t );
1665  *ent = ( pfm_dfl_smpl_entry_t * ) newent;
1666  return 0;
1667  }
1668 #if 0
1669  ( is_btb( native_pfm_index ) ) {
1670  // PMD48-63,39 on Montecito
1671  // PMD8-15,16 on Itanium 2
1672  }
1673 #endif
1674  else
1675  safety:
1676 #endif
1677  {
1678  *pc = ( caddr_t ) ( ( size_t ) ( ( *ent )->ip ) );
1679  ++( *ent );
1680  return ( 0 );
1681  }
1682 }
1683 
1684 static inline int
1685 process_smpl_buf( int num_smpl_pmds, int entry_size, ThreadInfo_t ** thr )
1686 {
1687  ( void ) num_smpl_pmds; /*unused */
1688  ( void ) entry_size; /*unused */
1689  int cidx = _perfmon2_vector.cmp_info.CmpIdx;
1690  pfm_dfl_smpl_entry_t *ent;
1691  uint64_t entry, count;
1692  pfm_dfl_smpl_hdr_t *hdr =
1693  ( ( pfm_context_t * ) ( *thr )->context[cidx] )->smpl_buf;
1694  int ret, profile_index, flags;
1695  unsigned int native_pfm_index;
1696  caddr_t pc = NULL;
1697  long long weight;
1698 
1700  count = hdr->hdr_count;
1701  ent = ( pfm_dfl_smpl_entry_t * ) ( hdr + 1 );
1702  entry = 0;
1703 
1704  SUBDBG( "This buffer has %llu samples in it.\n",
1705  ( unsigned long long ) count );
1706  while ( count-- ) {
1707  SUBDBG( "Processing sample entry %llu\n",
1708  ( unsigned long long ) entry );
1709  DEBUGCALL( DEBUG_SUBSTRATE, dump_smpl( ent ) );
1710 
1711  /* Find the index of the profile buffers if we are profiling on many events */
1712 
1713  ret =
1714  find_profile_index( ( *thr )->running_eventset[cidx], ent->ovfl_pmd,
1715  &flags, &native_pfm_index, &profile_index );
1716  if ( ret != PAPI_OK )
1717  return ( ret );
1718 
1719  weight = process_smpl_entry( native_pfm_index, flags, &ent, &pc );
1720 
1721  _papi_hwi_dispatch_profile( ( *thr )->running_eventset[cidx], pc,
1722  weight, profile_index );
1723 
1724  entry++;
1725  }
1726  return ( PAPI_OK );
1727 }
1728 
1729 
1730 /* This function used when hardware overflows ARE working
1731  or when software overflows are forced */
1732 
1733 static void
1734 _papi_pfm_dispatch_timer( int n, hwd_siginfo_t * info, void *uc )
1735 {
1736  _papi_hwi_context_t ctx;
1737 #ifdef HAVE_PFM_MSG_TYPE
1738  pfm_msg_t msg;
1739 #else
1740  pfarg_msg_t msg;
1741 #endif
1742  int ret, wanted_fd, fd = info->si_fd;
1743  caddr_t address;
1745  int cidx = _perfmon2_vector.cmp_info.CmpIdx;
1746 
1747  if ( thread == NULL ) {
1748  PAPIERROR( "thread == NULL in _papi_pfm_dispatch_timer!" );
1749  if ( n == _perfmon2_vector.cmp_info.hardware_intr_sig ) {
1750  ret = read( fd, &msg, sizeof ( msg ) );
1751  pfm_restart( fd );
1752  }
1753  return;
1754  }
1755 
1756  if ( thread->running_eventset[cidx] == NULL ) {
1757  PAPIERROR
1758  ( "thread->running_eventset == NULL in _papi_pfm_dispatch_timer!" );
1759  if ( n == _perfmon2_vector.cmp_info.hardware_intr_sig ) {
1760  ret = read( fd, &msg, sizeof ( msg ) );
1761  pfm_restart( fd );
1762  }
1763  return;
1764  }
1765 
1766  if ( thread->running_eventset[cidx]->overflow.flags == 0 ) {
1767  PAPIERROR
1768  ( "thread->running_eventset->overflow.flags == 0 in _papi_pfm_dispatch_timer!" );
1769  if ( n == _perfmon2_vector.cmp_info.hardware_intr_sig ) {
1770  ret = read( fd, &msg, sizeof ( msg ) );
1771  pfm_restart( fd );
1772  }
1773  return;
1774  }
1775 
1776  ctx.si = info;
1777  ctx.ucontext = ( hwd_ucontext_t * ) uc;
1778 
1779  if ( thread->running_eventset[cidx]->overflow.
1781  address = GET_OVERFLOW_ADDRESS( ctx );
1782  _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx, address, NULL,
1783  0, 0, &thread, cidx );
1784  } else {
1785  if ( thread->running_eventset[cidx]->overflow.flags ==
1787  wanted_fd =
1788  ( ( pfm_control_state_t * ) ( thread->running_eventset[cidx]->
1789  ctl_state ) )->ctx_fd;
1790  } else {
1791  wanted_fd = ( ( pfm_context_t * ) thread->context[cidx] )->ctx_fd;
1792  }
1793  if ( wanted_fd != fd ) {
1794  SUBDBG( "expected fd %d, got %d in _papi_hwi_dispatch_timer!",
1795  wanted_fd, fd );
1796  if ( n == _perfmon2_vector.cmp_info.hardware_intr_sig ) {
1797  ret = read( fd, &msg, sizeof ( msg ) );
1798  pfm_restart( fd );
1799  }
1800  return;
1801  }
1802  retry:
1803  ret = read( fd, &msg, sizeof ( msg ) );
1804  if ( ret == -1 ) {
1805  if ( errno == EINTR ) {
1806  SUBDBG( "read(%d) interrupted, retrying\n", fd );
1807  goto retry;
1808  } else {
1809  PAPIERROR( "read(%d): errno %d", fd, errno );
1810  }
1811  } else if ( ret != sizeof ( msg ) ) {
1812  PAPIERROR( "read(%d): short %d vs. %d bytes", fd, ret,
1813  sizeof ( msg ) );
1814  ret = -1;
1815  }
1816 
1817  if ( msg.type != PFM_MSG_OVFL ) {
1818  PAPIERROR( "unexpected msg type %d", msg.type );
1819  ret = -1;
1820  }
1821 #if 0
1822  if ( msg.pfm_ovfl_msg.msg_ovfl_tid != mygettid( ) ) {
1823  PAPIERROR( "unmatched thread id %lx vs. %lx",
1824  msg.pfm_ovfl_msg.msg_ovfl_tid, mygettid( ) );
1825  ret = -1;
1826  }
1827 #endif
1828 
1829  if ( ret != -1 ) {
1830  if ( ( thread->running_eventset[cidx]->state & PAPI_PROFILING ) &&
1831  !( thread->running_eventset[cidx]->profile.
1833  process_smpl_buf( 0, sizeof ( pfm_dfl_smpl_entry_t ), &thread );
1834  else {
1835  /* PAPI assumes that the overflow vector contains the register index of the
1836  overflowing native event. That is generally true, but Stephane used some
1837  tricks to offset the fixed counters on Core2 (Core? i7?) by 16. This hack
1838  corrects for that hack in a (hopefully) transparent manner */
1839  unsigned long i, vector = msg.pfm_ovfl_msg.msg_ovfl_pmds[0];
1840  pfm_control_state_t *ctl =
1841  ( pfm_control_state_t * ) thread->running_eventset[cidx]->
1842  ctl_state;
1843  for ( i = 0; i < ctl->in.pfp_event_count; i++ ) {
1844  /* We're only comparing to pmds[0]. A more robust implementation would
1845  compare to pmds[0-3]. The bit mask must be converted to an index
1846  for the comparison to work */
1847  if ( ctl->pd[i].reg_num ==
1848  ffsl( msg.pfm_ovfl_msg.msg_ovfl_pmds[0] ) - 1 ) {
1849  /* if a match is found, convert the index back to a bitmask */
1850  vector = 1 << i;
1851  break;
1852  }
1853  }
1854  _papi_hwi_dispatch_overflow_signal( ( void * ) &ctx,
1855  ( caddr_t ) ( ( size_t )
1856  msg.
1857  pfm_ovfl_msg.
1858  msg_ovfl_ip ),
1859  NULL, vector, 0, &thread,
1860  cidx );
1861  }
1862  }
1863 
1864  if ( ( ret = pfm_restart( fd ) ) ) {
1865  PAPIERROR( "pfm_restart(%d): %s", fd, strerror( ret ) );
1866  }
1867  }
1868 }
1869 
1870 static int
1872 {
1873  ( void ) ESI; /*unused */
1874  /* Process any remaining samples in the sample buffer */
1875  return ( process_smpl_buf( 0, sizeof ( pfm_dfl_smpl_entry_t ), &thread ) );
1876 }
1877 
1878 static int
1879 _papi_pfm_set_profile( EventSetInfo_t * ESI, int EventIndex, int threshold )
1880 {
1881  int cidx = _perfmon2_vector.cmp_info.CmpIdx;
1882  pfm_control_state_t *ctl = ( pfm_control_state_t * ) ( ESI->ctl_state );
1883  pfm_context_t *ctx = ( pfm_context_t * ) ( ESI->master->context[cidx] );
1884  pfarg_ctx_t newctx;
1885  void *buf_addr = NULL;
1886  pfm_dfl_smpl_arg_t buf_arg;
1887  pfm_dfl_smpl_hdr_t *hdr;
1888  int i, ret, ctx_fd;
1889 
1890  memset( &newctx, 0, sizeof ( newctx ) );
1891 
1892  if ( threshold == 0 ) {
1893  SUBDBG( "MUNMAP(%p,%lld)\n", ctx->smpl_buf,
1894  ( unsigned long long ) ctx->smpl.buf_size );
1895  munmap( ctx->smpl_buf, ctx->smpl.buf_size );
1896 
1897  i = close( ctl->ctx_fd );
1898  SUBDBG( "CLOSE fd %d returned %d\n", ctl->ctx_fd, i );
1899  (void) i;
1900 
1901  /* Thread has master context */
1902 
1903  ctl->ctx_fd = ctx->ctx_fd;
1904  ctl->ctx = &ctx->ctx;
1905  memset( &ctx->smpl, 0, sizeof ( buf_arg ) );
1906  ctx->smpl_buf = NULL;
1907  ret = _papi_pfm_set_overflow( ESI, EventIndex, threshold );
1908 //#warning "This should be handled somewhere else"
1909  ESI->state &= ~( PAPI_OVERFLOWING );
1910  ESI->overflow.flags &= ~( PAPI_OVERFLOW_HARDWARE );
1911 
1912  return ( ret );
1913  }
1914 
1915  memset( &buf_arg, 0, sizeof ( buf_arg ) );
1916  buf_arg.buf_size = 2 * getpagesize( );
1917 
1918  SUBDBG( "PFM_CREATE_CONTEXT(%p,%s,%p,%d)\n", &newctx, PFM_DFL_SMPL_NAME,
1919  &buf_arg, ( int ) sizeof ( buf_arg ) );
1920  if ( ( ret =
1921  pfm_create_context( &newctx, PFM_DFL_SMPL_NAME, &buf_arg,
1922  sizeof ( buf_arg ) ) ) == -1 ) {
1923  DEBUGCALL( DEBUG_SUBSTRATE, dump_smpl_arg( &buf_arg ) );
1924  PAPIERROR( "_papi_hwd_set_profile:pfm_create_context(): %s",
1925  strerror( errno ) );
1926  return ( PAPI_ESYS );
1927  }
1928  ctx_fd = ret;
1929  SUBDBG( "PFM_CREATE_CONTEXT returned fd %d\n", ctx_fd );
1930  tune_up_fd( ret );
1931 
1932  SUBDBG( "MMAP(NULL,%lld,%d,%d,%d,0)\n",
1933  ( unsigned long long ) buf_arg.buf_size, PROT_READ, MAP_PRIVATE,
1934  ctx_fd );
1935  buf_addr =
1936  mmap( NULL, ( size_t ) buf_arg.buf_size, PROT_READ, MAP_PRIVATE, ctx_fd,
1937  0 );
1938  if ( buf_addr == MAP_FAILED ) {
1939  PAPIERROR( "mmap(NULL,%d,%d,%d,%d,0): %s", buf_arg.buf_size, PROT_READ,
1940  MAP_PRIVATE, ctx_fd, strerror( errno ) );
1941  close( ctx_fd );
1942  return ( PAPI_ESYS );
1943  }
1944  SUBDBG( "Sample buffer is located at %p\n", buf_addr );
1945 
1946  hdr = ( pfm_dfl_smpl_hdr_t * ) buf_addr;
1947  SUBDBG( "hdr_cur_offs=%llu version=%u.%u\n",
1948  ( unsigned long long ) hdr->hdr_cur_offs,
1949  PFM_VERSION_MAJOR( hdr->hdr_version ),
1950  PFM_VERSION_MINOR( hdr->hdr_version ) );
1951 
1952  if ( PFM_VERSION_MAJOR( hdr->hdr_version ) < 1 ) {
1953  PAPIERROR( "invalid buffer format version %d",
1954  PFM_VERSION_MAJOR( hdr->hdr_version ) );
1955  munmap( buf_addr, buf_arg.buf_size );
1956  close( ctx_fd );
1957  return PAPI_ESYS;
1958  }
1959 
1960  ret = _papi_pfm_set_overflow( ESI, EventIndex, threshold );
1961  if ( ret != PAPI_OK ) {
1962  munmap( buf_addr, buf_arg.buf_size );
1963  close( ctx_fd );
1964  return ( ret );
1965  }
1966 
1967  /* Look up the native event code */
1968 
1970  pfarg_pmd_t *pd;
1971  int pos, native_index;
1972  pd = ctl->pd;
1973  pos = ESI->EventInfoArray[EventIndex].pos[0];
1974  native_index =
1975  ( ( pfm_register_t * ) ( ESI->NativeInfoArray[pos].ni_bits ) )->
1976  event;
1977  setup_ear_event( native_index, &pd[pos], ESI->profile.flags );
1978  }
1979 
1980  if ( ESI->profile.flags & PAPI_PROFIL_RANDOM ) {
1981  pfarg_pmd_t *pd;
1982  int pos;
1983  pd = ctl->pd;
1984  pos = ESI->EventInfoArray[EventIndex].pos[0];
1985  pd[pos].reg_random_seed = 5;
1986  pd[pos].reg_random_mask = 0xff;
1987  }
1988 
1989  /* Now close our context it is safe */
1990 
1991  // close(ctx->ctx_fd);
1992 
1993  /* Copy the new data to the threads context control block */
1994 
1995  ctl->ctx_fd = ctx_fd;
1996  memcpy( &ctx->smpl, &buf_arg, sizeof ( buf_arg ) );
1997  ctx->smpl_buf = buf_addr;
1998 
1999  return ( PAPI_OK );
2000 }
2001 
2002 
2003 
2004 static int
2005 _papi_pfm_set_overflow( EventSetInfo_t * ESI, int EventIndex, int threshold )
2006 {
2007  pfm_control_state_t *this_state =
2008  ( pfm_control_state_t * ) ( ESI->ctl_state );
2009  int j, retval = PAPI_OK, *pos;
2010 
2011  /* Which counter are we on, this looks suspicious because of the pos[0],
2012  but this could be because of derived events. We should do more here
2013  to figure out exactly what the position is, because the event may
2014  actually have more than one position. */
2015 
2016  pos = ESI->EventInfoArray[EventIndex].pos;
2017  j = pos[0];
2018  SUBDBG( "Hardware counter %d used in overflow, threshold %d\n", j,
2019  threshold );
2020 
2021  if ( threshold == 0 ) {
2022  /* If this counter isn't set to overflow */
2023 
2024  if ( ( this_state->pd[j].reg_flags & PFM_REGFL_OVFL_NOTIFY ) == 0 )
2025  return ( PAPI_EINVAL );
2026 
2027  /* Remove the signal handler */
2028 
2029  retval = _papi_hwi_stop_signal( _perfmon2_vector.cmp_info.hardware_intr_sig );
2030  if ( retval != PAPI_OK )
2031  return ( retval );
2032 
2033  /* Disable overflow */
2034 
2035  this_state->pd[j].reg_flags ^= PFM_REGFL_OVFL_NOTIFY;
2036 
2037  /*
2038  * we may want to reset the other PMDs on
2039  * every overflow. If we do not set
2040  * this, the non-overflowed counters
2041  * will be untouched.
2042 
2043  if (inp.pfp_event_count > 1)
2044  this_state->pd[j].reg_reset_pmds[0] ^= 1UL << counter_to_reset */
2045 
2046  /* Clear the overflow period */
2047 
2048  this_state->pd[j].reg_value = 0;
2049  this_state->pd[j].reg_long_reset = 0;
2050  this_state->pd[j].reg_short_reset = 0;
2051  this_state->pd[j].reg_random_seed = 0;
2052  this_state->pd[j].reg_random_mask = 0;
2053  } else {
2054  /* Enable the signal handler */
2055 
2056  retval =
2057  _papi_hwi_start_signal( _perfmon2_vector.cmp_info.hardware_intr_sig, 1,
2058  _perfmon2_vector.cmp_info.CmpIdx );
2059  if ( retval != PAPI_OK )
2060  return ( retval );
2061 
2062  /* Set it to overflow */
2063 
2064  this_state->pd[j].reg_flags |= PFM_REGFL_OVFL_NOTIFY;
2065 
2066  /*
2067  * we may want to reset the other PMDs on
2068  * every overflow. If we do not set
2069  * this, the non-overflowed counters
2070  * will be untouched.
2071 
2072  if (inp.pfp_event_count > 1)
2073  this_state->pd[j].reg_reset_pmds[0] |= 1UL << counter_to_reset */
2074 
2075  /* Set the overflow period */
2076 
2077  this_state->pd[j].reg_value = -( unsigned long long ) threshold + 1;
2078  this_state->pd[j].reg_short_reset =
2079  -( unsigned long long ) threshold + 1;
2080  this_state->pd[j].reg_long_reset =
2081  -( unsigned long long ) threshold + 1;
2082  }
2083  return ( retval );
2084 }
2085 
2086 static int
2088 {
2089  pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
2090  pfmlib_input_param_t *inp = &ctl->in;
2091  pfmlib_output_param_t *outp = &ctl->out;
2092  pfarg_pmd_t *pd = ctl->pd;
2093  pfarg_pmc_t *pc = ctl->pc;
2094  pfarg_setdesc_t *set = ctl->set;
2095  pfarg_setinfo_t *setinfo = ctl->setinfo;
2096 
2097  memset( inp, 0, sizeof ( *inp ) );
2098  memset( outp, 0, sizeof ( *inp ) );
2099  memset( pc, 0, sizeof ( ctl->pc ) );
2100  memset( pd, 0, sizeof ( ctl->pd ) );
2101  memset( set, 0, sizeof ( ctl->set ) );
2102  memset( setinfo, 0, sizeof ( ctl->setinfo ) );
2103  /* Will be filled by update now...until this gets another arg */
2104  ctl->ctx = NULL;
2105  ctl->ctx_fd = -1;
2106  ctl->load = NULL;
2107  set_domain( ctl, _perfmon2_vector.cmp_info.default_domain );
2108  return ( PAPI_OK );
2109 }
2110 
2111 static int
2113 {
2114  int i, j;
2115  for ( i = 0; i < ESI->NativeCount; i++ ) {
2117  ( ESI->NativeInfoArray[i].ni_event,
2118  ESI->NativeInfoArray[i].ni_bits ) != PAPI_OK )
2119  goto bail;
2120  }
2121  return PAPI_OK;
2122  bail:
2123  for ( j = 0; j < i; j++ )
2124  memset( ESI->NativeInfoArray[j].ni_bits, 0x0,
2125  sizeof ( pfm_register_t ) );
2126  return PAPI_ECNFLCT;
2127 }
2128 
2129 /* This function clears the current contents of the control structure and
2130  updates it with whatever resources are allocated for all the native events
2131  in the native info structure array. */
2132 
2133 static int
2135  NativeInfo_t * native, int count,
2136  hwd_context_t * ctx0 )
2137 {
2138  pfm_control_state_t *ctl = ( pfm_control_state_t * ) ctl0;
2139  pfm_context_t *ctx = ( pfm_context_t * ) ctx0;
2140  int i = 0, ret;
2141  int last_reg_set = 0, reg_set_done = 0, offset = 0;
2142  pfmlib_input_param_t tmpin, *inp = &ctl->in;
2143  pfmlib_output_param_t tmpout, *outp = &ctl->out;
2144  pfarg_pmd_t *pd = ctl->pd;
2145 
2146  if ( count == 0 ) {
2147  SUBDBG( "Called with count == 0\n" );
2148  inp->pfp_event_count = 0;
2149  outp->pfp_pmc_count = 0;
2150  memset( inp->pfp_events, 0x0, sizeof ( inp->pfp_events ) );
2151  return ( PAPI_OK );
2152  }
2153 
2154  memcpy( &tmpin, inp, sizeof ( tmpin ) );
2155  memcpy( &tmpout, outp, sizeof ( tmpout ) );
2156 
2157  for ( i = 0; i < count; i++ ) {
2158  SUBDBG
2159  ( "Stuffing native event index %d (code %#x) into input structure.\n",
2160  i, ( ( pfm_register_t * ) native[i].ni_bits )->event );
2161  memcpy( inp->pfp_events + i, native[i].ni_bits,
2162  sizeof ( pfmlib_event_t ) );
2163  }
2164  inp->pfp_event_count = count;
2165 
2166  /* let the library figure out the values for the PMCS */
2167 
2168  ret = compute_kernel_args( ctl );
2169  if ( ret != PAPI_OK ) {
2170  /* Restore values */
2171  memcpy( inp, &tmpin, sizeof ( tmpin ) );
2172  memcpy( outp, &tmpout, sizeof ( tmpout ) );
2173  return ( ret );
2174  }
2175 
2176  /* Update the native structure, because the allocation is done here. */
2177 
2178  last_reg_set = pd[0].reg_set;
2179  for ( i = 0; i < count; i++ ) {
2180  if ( pd[i].reg_set != last_reg_set ) {
2181  offset += reg_set_done;
2182  reg_set_done = 0;
2183  }
2184  reg_set_done++;
2185 
2186  native[i].ni_position = i;
2187  SUBDBG( "native event index %d (code %#x) is at PMD offset %d\n", i,
2188  ( ( pfm_register_t * ) native[i].ni_bits )->event,
2189  native[i].ni_position );
2190  }
2191 
2192  /* If structure has not yet been filled with a context, fill it
2193  from the thread's context. This should happen in init_control_state
2194  when we give that a *ctx argument */
2195 
2196  if ( ctl->ctx == NULL ) {
2197  ctl->ctx = &ctx->ctx;
2198  ctl->ctx_fd = ctx->ctx_fd;
2199  ctl->load = &ctx->load;
2200  }
2201 
2202  return ( PAPI_OK );
2203 }
2204 
2205 
2206 papi_vector_t _perfmon2_vector = {
2207  .cmp_info = {
2208  /* default component information (unspecified values initialized to 0) */
2209  .name = "perfmon",
2210  .description = "Linux perfmon2 CPU counters",
2211  .version = "3.8",
2212 
2213  .default_domain = PAPI_DOM_USER,
2214  .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
2215  .default_granularity = PAPI_GRN_THR,
2216  .available_granularities = PAPI_GRN_THR,
2217 
2218  .hardware_intr = 1,
2219  .kernel_multiplex = 1,
2220  .kernel_profile = 1,
2221  .num_mpx_cntrs = PFMLIB_MAX_PMDS,
2222 
2223  /* component specific cmp_info initializations */
2224  .fast_real_timer = 1,
2225  .fast_virtual_timer = 0,
2226  .attach = 1,
2227  .attach_must_ptrace = 1,
2228  },
2229 
2230  /* sizes of framework-opaque component-private structures */
2231  .size = {
2232  .context = sizeof ( pfm_context_t ),
2233  .control_state = sizeof ( pfm_control_state_t ),
2234  .reg_value = sizeof ( pfm_register_t ),
2235  .reg_alloc = sizeof ( pfm_reg_alloc_t ),
2236  },
2237  /* function pointers in this component */
2238  .init_control_state = _papi_pfm_init_control_state,
2239  .start = _papi_pfm_start,
2240  .stop = _papi_pfm_stop,
2241  .read = _papi_pfm_read,
2242  .shutdown_thread = _papi_pfm_shutdown,
2243  .shutdown_component = _papi_pfm_shutdown_component,
2244  .ctl = _papi_pfm_ctl,
2245  .update_control_state = _papi_pfm_update_control_state,
2246  .set_domain = set_domain,
2247  .reset = _papi_pfm_reset,
2248  .set_overflow = _papi_pfm_set_overflow,
2249  .set_profile = _papi_pfm_set_profile,
2250  .stop_profiling = _papi_pfm_stop_profiling,
2251  .init_component = _papi_pfm_init_component,
2252  .dispatch_timer = _papi_pfm_dispatch_timer,
2253  .init_thread = _papi_pfm_init_thread,
2254  .allocate_registers = _papi_pfm_allocate_registers,
2255  .write = _papi_pfm_write,
2256 
2257  /* from the counter name library */
2258  .ntv_enum_events = _papi_libpfm_ntv_enum_events,
2259  .ntv_name_to_code = _papi_libpfm_ntv_name_to_code,
2260  .ntv_code_to_name = _papi_libpfm_ntv_code_to_name,
2261  .ntv_code_to_descr = _papi_libpfm_ntv_code_to_descr,
2262  .ntv_code_to_bits = _papi_libpfm_ntv_code_to_bits,
2263 
2264 };
static int process_smpl_buf(int num_smpl_pmds, int entry_size, ThreadInfo_t **thr)
Definition: perfmon.c:1685
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:625
#define PAPI_HUGE_STR_LEN
Definition: fpapi.h:42
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int _papi_libpfm_init(papi_vector_t *my_vector, int cidx)
ssize_t read(int fd, void *buf, size_t count)
Definition: appio.c:225
memset(eventId, 0, size)
static int get_string_from_file(char *file, char *str, int len)
Definition: perfmon.c:731
int errno
int close(int fd)
Definition: appio.c:175
double f(double a)
Definition: cpi.c:23
#define PAPI_ENOMEM
Definition: fpapi.h:107
#define PAPI_GRN_SYS_CPU
Definition: fpapi.h:72
#define PAPI_VENDOR_SUN
Definition: papi.h:350
#define LBPL
Definition: perfmon.c:1394
int _papi_pfm_read(hwd_context_t *ctx0, hwd_control_state_t *ctl0, long long **events, int flags)
Definition: perfmon.c:960
int _papi_pfm_start(hwd_context_t *ctx0, hwd_control_state_t *ctl0)
Definition: perfmon.c:1040
EventSetInfo_t * ESI
hwd_register_t * ni_bits
pfarg_setinfo_t setinfo[PFMLIB_MAX_PMDS]
Definition: perfmon.h:71
long long flags
Definition: iozone.c:12330
#define PAPI_DEF_ITIMER_NS
Definition: papi.h:453
int _papi_pfm_shutdown_component()
Definition: perfmon.c:863
EventSetInfo_t * ESI
static int _papi_pfm_init_thread(hwd_context_t *thr_ctx)
Definition: perfmon.c:869
#define PAPI_INSTR_ADDRESS
Definition: papi.h:451
static int attach(hwd_control_state_t *ctl, unsigned long tid)
Definition: perfmon.c:593
static void _papi_pfm_dispatch_timer(int n, hwd_siginfo_t *info, void *uc)
Definition: perfmon.c:1734
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
#define PAPI_PROFIL_DATA_EAR
Definition: papi.h:402
static int detect_timeout_and_unavail_pmu_regs(pfmlib_regmask_t *r_pmcs, pfmlib_regmask_t *r_pmds, unsigned long *timeout_ns)
Definition: perfmon.c:341
_papi_int_addr_range_t address_range
static int detach(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: perfmon.c:645
pfarg_load_t load
Definition: perfmon.h:89
#define BPL
Definition: perfmon.c:1393
int ns
Definition: iozone.c:20358
off64_t offset
Definition: iozone.c:1279
#define PAPI_DATA_ADDRESS
Definition: papi.h:450
pfarg_setdesc_t set[PFMLIB_MAX_PMDS]
Definition: perfmon.h:69
int _papi_libpfm_ntv_enum_events(unsigned int *EventCode, int modifier)
int fd
Definition: iozone.c:1291
pfarg_pmd_t pd[PFMLIB_MAX_PMDS]
Definition: perfmon.h:75
static int _perfmon2_pfm_pmu_type
Definition: perfmon.c:50
for(i=0;i<=max_y;i++)
Definition: iozone.c:11615
device[deviceId] domain[domainId] event
Definition: linux-cuda.c:306
static int set_irange(hwd_context_t *ctx, hwd_control_state_t *current_state, _papi_int_option_t *option)
Definition: perfmon-ia64.c:919
#define PAPI_PROFIL_RANDOM
Definition: fpapi.h:76
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
struct cache_ent * entry
Definition: libasync.c:1170
static int process_smpl_entry(unsigned int native_pfm_index, int flags, pfm_dfl_smpl_entry_t **ent, caddr_t *pc)
Definition: perfmon.c:1443
static int set_granularity(hwd_control_state_t *this_state, int domain)
Definition: perfmon.c:702
#define PAPI_GRN_SYS
Definition: fpapi.h:71
#define PAPI_DOM_OTHER
Definition: fpapi.h:23
static pid_t mygettid(void)
Definition: darwin-common.h:11
fclose(thread_wqfd)
#define PAPI_DOM_KERNEL
Definition: fpapi.h:22
#define PAPI_GRN_PROC
Definition: fpapi.h:69
void
Definition: iozone.c:18627
return PAPI_EINVAL
Definition: linux-nvml.c:408
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
static void dump_pmc(pfm_control_state_t *ctl)
Definition: perfmon.c:108
static int set_default_domain(EventSetInfo_t *zero, int domain)
Definition: aix.c:510
#define PAPI_OVERFLOWING
Definition: fpapi.h:33
unsigned int cntr_umasks
Definition: papi.h:663
#define PAPI_PROFILING
Definition: fpapi.h:34
#define PAPI_ECNFLCT
Definition: fpapi.h:113
char kernel_version[PAPI_MIN_STR_LEN]
Definition: papi.h:631
Return codes and api definitions.
int init_proc_thread_timer(hwd_context_t *thr_ctx)
_papi_int_itimer_t itimer
_papi_int_attach_t attach
long long ret
Definition: iozone.c:1346
unsigned long tid
pfmlib_output_param_t out
Definition: perfmon.h:63
void * smpl_buf
Definition: perfmon.h:93
int _papi_libpfm_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len)
char disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:632
static int _papi_pfm_update_control_state(hwd_control_state_t *ctl0, NativeInfo_t *native, int count, hwd_context_t *ctx0)
Definition: perfmon.c:2134
static int setup_ear_event(unsigned int native_index, pfarg_pmd_t *pd, int flags)
Definition: perfmon.c:1402
int _papi_pfm_init_component(int cidx)
Definition: perfmon.c:750
int i
Definition: fileop.c:140
#define PAPI_ENOSUPP
Definition: fpapi.h:123
EventSetOverflowInfo_t overflow
#define PAPI_GRN_PROCG
Definition: fpapi.h:70
char buf[200]
Definition: iozone.c:19609
#define PAPI_OVERFLOW_HARDWARE
Definition: papi.h:410
unsigned int fast_real_timer
Definition: papi.h:655
PAPI_os_info_t _papi_os_info
Definition: aix.c:1210
struct _ThreadInfo * master
#define PAPI_VENDOR_IBM
Definition: papi.h:348
static int compute_kernel_args(hwd_control_state_t *ctl0)
Definition: perfmon.c:400
#define PAPI_DOM_SUPERVISOR
Definition: fpapi.h:24
static void dump_sets(pfarg_setdesc_t *set, int num_sets)
Definition: perfmon.c:66
static void dump_setinfo(pfarg_setinfo_t *setinfo, int num_sets)
Definition: perfmon.c:82
free(dummyfile[xx])
static int cidx
Definition: event_info.c:40
static pfmlib_regmask_t _perfmon2_pfm_unavailable_pmds
Definition: perfmon.c:52
unsigned int fast_counter_read
Definition: papi.h:654
#define PAPI_ECMP
Definition: fpapi.h:109
pfarg_ctx_t ctx
Definition: perfmon.h:87
static void dump_smpl_hdr(pfm_dfl_smpl_hdr_t *hdr)
Definition: perfmon.c:157
papi_vector_t _perfmon2_vector
Definition: perfmon.c:45
static int _papi_pfm_allocate_registers(EventSetInfo_t *ESI)
Definition: perfmon.c:2112
hwd_ucontext_t * ucontext
int pfm_reg_alloc_t
Definition: perfmon.h:46
int _papi_pfm_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
Definition: perfmon.c:904
static int native
Definition: event_info.c:39
hwd_context_t ** context
Definition: threads.h:28
void * thread(void *arg)
Definition: kufrin.c:31
static int _papi_pfm_init_control_state(hwd_control_state_t *ctl0)
Definition: perfmon.c:2087
void *long long tid
Definition: iozone.c:18586
static int set_domain(hwd_control_state_t *ctl0, int domain)
Definition: perfmon.c:667
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define PAPI_PROFIL_INST_EAR
Definition: papi.h:403
long long
Definition: iozone.c:19827
_papi_int_granularity_t granularity
EventSetInfo_t * ESI
#define DEBUGCALL(a, b)
Definition: perfmon.h:39
void PAPIERROR(char *format,...)
pfm_dfl_smpl_arg_t smpl
Definition: perfmon.h:91
int _papi_hwi_start_signal(int signal, int need_context, int cidx)
Definition: extras.c:401
#define PAPI_DOMAIN
Definition: fpapi.h:50
char events[MAX_EVENTS][BUFSIZ]
#define PAPI_ATTACH
Definition: fpapi.h:62
static int find_profile_index(EventSetInfo_t *ESI, int pmd, int *flags, unsigned int *native_index, int *profile_index)
Definition: perfmon.c:1307
pfmlib_input_param_t in
Definition: perfmon.h:61
int _papi_hwi_stop_signal(int signal)
Definition: extras.c:441
long long counts[PFMLIB_MAX_PMDS]
Definition: perfmon.h:77
unsigned uint
Definition: perfmon.c:40
#define PAPI_GRANUL
Definition: fpapi.h:52
int _papi_pfm_stop(hwd_context_t *ctx0, hwd_control_state_t *ctl0)
Definition: perfmon.c:1123
_papi_int_multiplex_t multiplex
NativeInfo_t * NativeInfoArray
int _papi_libpfm_error(int pfm_error)
EventInfo_t * EventInfoArray
#define PAPI_DEF_MPX_NS
Definition: fpapi.h:53
int _papi_pfm_shutdown(hwd_context_t *ctx0)
Definition: perfmon.c:1288
#define PAPI_ESYS
Definition: fpapi.h:108
int threshold
int _papi_libpfm_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len)
#define PAPI_VENDOR_CRAY
Definition: papi.h:349
papi_mdi_t _papi_hwi_system_info
Definition: papi_internal.c:57
PAPI_hw_info_t hw_info
again struct sockaddr sizeof(struct sockaddr_in))
#define PAPI_DETACH
Definition: fpapi.h:66
pfarg_load_t * load
Definition: perfmon.h:57
#define PAPI_VENDOR_INTEL
Definition: papi.h:346
pfmlib_event_t pfm_register_t
Definition: perfctr-x86.h:140
int pos[PAPI_EVENTS_IN_DERIVED_EVENT]
int vendor
Definition: papi.h:782
struct sigcontext hwd_ucontext_t
Definition: aix-context.h:10
static int set_inherit(int arg)
Definition: perfmon.c:724
static int _papi_pfm_stop_profiling(ThreadInfo_t *thread, EventSetInfo_t *ESI)
Definition: perfmon.c:1871
static int check_multiplex_timeout(int ctx_fd, unsigned long *timeout_ns)
Definition: perfmon.c:306
#define PAPI_EBUG
Definition: fpapi.h:111
#define PAPI_OVERFLOW_FORCE_SW
Definition: papi.h:409
static int set_drange(hwd_context_t *ctx, hwd_control_state_t *current_state, _papi_int_option_t *option)
Definition: perfmon-ia64.c:767
#define PAPI_DEF_ITIMER
Definition: papi.h:452
EventSetInfo_t ** running_eventset
Definition: threads.h:30
static int _papi_pfm_set_profile(EventSetInfo_t *ESI, int EventIndex, int threshold)
Definition: perfmon.c:1879
void _papi_hwi_dispatch_profile(EventSetInfo_t *ESI, caddr_t pc, long long over, int profile_index)
Definition: extras.c:163
int
Definition: iozone.c:18528
#define MAP_FAILED
Definition: iozone.c:336
inline_static ThreadInfo_t * _papi_hwi_lookup_thread(int custom_tid)
Definition: threads.h:92
int _papi_libpfm_ntv_name_to_code(char *name, unsigned int *event_code)
pfarg_ctx_t * ctx
Definition: perfmon.h:55
int _papi_pfm_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
Definition: perfmon.c:1194
int ctx_fd
Definition: perfmon.h:86
#define PAPI_NATIVE_AND_MASK
#define PAPI_PROFIL_FORCE_SW
Definition: papi.h:401
static int round_requested_ns(int ns)
Definition: perfmon.c:1183
char support_version[PAPI_MIN_STR_LEN]
Definition: papi.h:630
#define PAPI_ECLOST
Definition: fpapi.h:110
int _papi_libpfm_ntv_code_to_bits(unsigned int EventCode, hwd_register_t *bits)
_papi_int_domain_t domain
char model_string[PAPI_MAX_STR_LEN]
Definition: papi.h:785
hwd_siginfo_t * si
#define PAPI_DOM_USER
Definition: fpapi.h:21
int _papi_hwi_dispatch_overflow_signal(void *papiContext, caddr_t address, int *isHardware, long long overflow_bit, int genOverflowBit, ThreadInfo_t **t, int cidx)
Definition: extras.c:214
EventSetInfo_t * ESI
int _papi_pfm_write(hwd_context_t *ctx, hwd_control_state_t *ctl, long long *from)
Definition: perfmon.c:931
EventSetProfileInfo_t profile
pfarg_pmc_t pc[PFMLIB_MAX_PMCS]
Definition: perfmon.h:73
return
Definition: iozone.c:22170
hwd_control_state_t * ctl_state
long j
Definition: iozone.c:19135
static void dump_pmd(pfm_control_state_t *ctl)
Definition: perfmon.c:124
int _papi_pfm_write_pmds(pfm_context_t *ctx, pfm_control_state_t *ctl)
Definition: perfmon.c:227
ssize_t retval
Definition: libasync.c:338
long long tmp
Definition: iozone.c:12031
static int _papi_pfm_set_overflow(EventSetInfo_t *ESI, int EventIndex, int threshold)
Definition: perfmon.c:2005
int tune_up_fd(int ctx_fd)
Definition: perfmon.c:547
static pfmlib_regmask_t _perfmon2_pfm_unavailable_pmcs
Definition: perfmon.c:51
#define GET_OVERFLOW_ADDRESS(ctx)
Definition: aix-context.h:12
#define PFM_MAX_PMCDS
Definition: perfmon.c:188
#define PAPI_GRN_THR
Definition: fpapi.h:67
int _papi_pfm_write_pmcs(pfm_context_t *ctx, pfm_control_state_t *ctl)
Definition: perfmon.c:191
if(gettimeofday(&tp,(struct timezone *) NULL)==-1) perror("gettimeofday")
int _papi_pfm_read_pmds(pfm_context_t *ctx, pfm_control_state_t *ctl)
Definition: perfmon.c:266
static void pfm_bv_set(uint64_t *bv, uint16_t rnum)
Definition: perfmon.c:1396
#define PAPI_MULTIPLEX
Definition: fpapi.h:48
EventSetInfo_t * ESI
#define PAPI_VENDOR_AMD
Definition: papi.h:347
int n
Definition: mendes-alt.c:164
static void dump_smpl(pfm_dfl_smpl_entry_t *entry)
Definition: perfmon.c:174
#define DEBUG_SUBSTRATE
Definition: papi_debug.h:27
static void dump_smpl_arg(pfm_dfl_smpl_arg_t *arg)
Definition: perfmon.c:58