PAPI  5.4.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
papi_internal.c
Go to the documentation of this file.
1 /****************************/
2 /* THIS IS OPEN SOURCE CODE */
3 /****************************/
4 
5 /*
6 * File: papi_internal.c
7 *
8 * Author: Philip Mucci
9 * mucci@cs.utk.edu
10 * Mods: dan terpstra
11 * terpstra@cs.utk.edu
12 * Mods: Min Zhou
13 * min@cs.utk.edu
14 * Mods: Kevin London
15 * london@cs.utk.edu
16 * Mods: Per Ekman
17 * pek@pdc.kth.se
18 * Mods: Haihang You
19 * you@cs.utk.edu
20 * Mods: Maynard Johnson
21 * maynardj@us.ibm.com
22 * Mods: Brian Sheely
23 * bsheely@eecs.utk.edu
24 * Mods: <Gary Mohr>
25 * <gary.mohr@bull.com>
26 * Mods: <your name here>
27 * <your email address>
28 */
29 
30 #include <stdarg.h>
31 #include <stdio.h>
32 #include <errno.h>
33 #include <string.h>
34 #include <ctype.h>
35 
36 #include "papi.h"
37 #include "papi_internal.h"
38 #include "papi_vector.h"
39 #include "papi_memory.h"
40 #include "sw_multiplex.h"
41 #include "extras.h"
42 #include "papi_preset.h"
43 #include "cpus.h"
44 
45 #include "papi_common_strings.h"
46 
47 #include "papi_user_events.h"
48 
49 /* Advanced definitons */
50 static int default_debug_handler( int errorCode );
51 static long long handle_derived( EventInfo_t * evi, long long *from );
52 
53 /* Global definitions used by other files */
60 
61 /*****************************/
62 /* Native Event Mapping Code */
63 /*****************************/
64 
65 #define NATIVE_EVENT_CHUNKSIZE 1024
66 
68  int cidx;
70  int ntv_idx;
71  char *evt_name;
72 };
73 
74 
75 // The following array is indexed by the papi event code (after the native bit has been removed)
77 static int num_native_events=0;
78 static int num_native_chunks=0;
79 
80 char **_papi_errlist= NULL;
81 static int num_error_chunks = 0;
82 
83 
84 // pointer to event:mask string associated with last enum call to a components
85 // will be NULL for non libpfm4 components
86 // this is needed because libpfm4 event codes and papi event codes do not contain mask information
87 char *papi_event_string = NULL;
88 void
89 _papi_hwi_set_papi_event_string (const char *event_string) {
90  INTDBG("event_string: %s\n", event_string);
91  if (papi_event_string != NULL) {
93  papi_event_string = NULL;
94  }
95  if (event_string != NULL) {
96  papi_event_string = strdup(event_string);
97  }
98  return;
99 }
100 char *
102  INTDBG("papi_event_string: %s\n", papi_event_string);
103  return papi_event_string;
104 }
105 void
107  if (papi_event_string != NULL) {
109  papi_event_string = NULL;
110  }
111  return;
112 }
113 // A place to keep the current papi event code so some component functions can fetch its value
114 // The current event code can be stored here prior to component calls and cleared after the component returns
115 static unsigned int papi_event_code = -1;
116 static int papi_event_code_changed = -1;
117 void
118 _papi_hwi_set_papi_event_code (unsigned int event_code, int update_flag) {
119  INTDBG("new event_code: %#x, update_flag: %d, previous event_code: %#x\n", event_code, update_flag, papi_event_code);
120 
121  // if call is just to reset and start over, set both flags to show nothing saved yet
122  if (update_flag < 0) {
124  papi_event_code = -1;
125  return;
126  }
127 
128  // if 0, it is being set prior to calling a component, if >0 it is being changed by the component
129  papi_event_code_changed = update_flag;
130  // save the event code passed in
131  papi_event_code = event_code;
132  return;
133 }
134 unsigned int
136  INTDBG("papi_event_code: %#x\n", papi_event_code);
137  return papi_event_code;
138 }
139 /* Get the index into the ESI->NativeInfoArray for the current PAPI event code */
140 int
141 _papi_hwi_get_ntv_idx (unsigned int papi_evt_code) {
142  INTDBG("ENTER: papi_evt_code: %#x\n", papi_evt_code);
143 
144  int result;
145  int event_index;
146 
147  if (papi_evt_code == 0) {
148  INTDBG("EXIT: PAPI_ENOEVNT, invalid papi event code\n");
149  return PAPI_ENOEVNT;
150  }
151 
152  event_index=papi_evt_code&PAPI_NATIVE_AND_MASK;
153  if ((event_index<0) || (event_index>=num_native_events)) {
154  INTDBG("EXIT: PAPI_ENOEVNT, invalid index into native event array\n");
155  return PAPI_ENOEVNT;
156  }
157 
158  result=_papi_native_events[event_index].ntv_idx;
159 
160  INTDBG("EXIT: result: %d\n", result);
161  return result;
162 }
163 
164 //
165 // Check for the presence of a component name or pmu name in the event string.
166 // If found check if it matches this component or one of the pmu's supported by this component.
167 //
168 // returns true if the event could be for this component and false if it is not for this component.
169 // if there is no component or pmu name then it could be for this component and returns true.
170 //
171 static int
173  INTDBG("ENTER: cidx: %d, event_name: %s\n", cidx, event_name);
174  int i;
175  int component_name = 0;
176  int pmu_name = 0;
177  char *wptr = NULL;
178 
179  // if event does not have a component name or pmu name, return to show it could be supported by this component
180  // when component and pmu names are not provided, we just have to call the components to see if they recognize the event
181  //
182 
183  // look for component names first
184  if ((wptr = strstr(event_name, ":::")) != NULL) {
185  component_name = 1;
186  } else if ((wptr = strstr(event_name, "::")) != NULL) {
187  pmu_name = 1;
188  } else {
189  INTDBG("EXIT: No Component or PMU name in event string, try this component\n");
190  // need to force all components to be called to find owner of this event
191  // ???? can we assume the default pmu when no component or pmu name is provided ????
192  return 1;
193  }
194 
195  // get a temporary copy of the component or pmu name
196  int name_len = wptr - event_name;
197  wptr = strdup(event_name);
198  wptr[name_len] = '\0';
199 
200  // if a component name was found, compare it to the component name in the component info structure
201  if (component_name) {
202 // INTDBG("component_name: %s\n", _papi_hwd[cidx]->cmp_info.name);
203  if (strcmp (wptr, _papi_hwd[cidx]->cmp_info.name) == 0) {
204  free (wptr);
205  INTDBG("EXIT: Component %s supports this event\n", _papi_hwd[cidx]->cmp_info.name);
206  return 1;
207  }
208  }
209 
210  // if a pmu name was found, compare it to the pmu name list if the component info structure (if there is one)
211  if (pmu_name) {
212  for ( i=0 ; i<PAPI_PMU_MAX ; i++) {
213  if (_papi_hwd[cidx]->cmp_info.pmu_names[i] == NULL) {
214  continue;
215  }
216 // INTDBG("pmu_name[%d]: %p (%s)\n", i, _papi_hwd[cidx]->cmp_info.pmu_names[i], _papi_hwd[cidx]->cmp_info.pmu_names[i]);
217  if (strcmp (wptr, _papi_hwd[cidx]->cmp_info.pmu_names[i]) == 0) {
218  INTDBG("EXIT: Component %s supports PMU %s and this event\n", _papi_hwd[cidx]->cmp_info.name, wptr);
219  free (wptr);
220  return 1;
221  }
222  }
223  }
224 
225  free (wptr);
226  INTDBG("EXIT: Component does not support this event\n");
227  return 0;
228 }
229 
242 int
243 _papi_hwi_prefix_component_name( char *component_name, char *event_name, char *out, int out_len)
244 {
245  int size1, size2;
246  char temp[out_len];
247 
248  size1 = strlen(event_name);
249  size2 = strlen(component_name);
250 
251 /* sanity checks */
252  if ( size1 == 0 ) {
253  return (PAPI_EBUG); /* hopefully event_name always has length?! */
254  }
255 
256  if ( size1 >= out_len )
257  return (PAPI_ENOMEM);
258 
259 /* Guard against event_name == out */
260  memcpy( temp, event_name, out_len );
261 
262 /* no component name to prefix */
263  if ( size2 == 0 ) {
264  sprintf(out, "%s%c", temp, '\0' );
265  return (PAPI_OK);
266  }
267 
268 /* Don't prefix 'cpu' component names for now */
269  if ( strstr(component_name, "pe") ||
270  strstr(component_name, "bgq") ||
271  strstr(component_name, "bgp") ) {
272  sprintf( out, "%s%c", temp, '\0');
273  return (PAPI_OK);
274  }
275 
276 /* strlen(component_name) + ::: + strlen(event_name) + NULL */
277  if ( size1+size2+3+1 > out_len )
278  return (PAPI_ENOMEM);
279 
280  sprintf( out, "%s:::%s%c" , component_name, temp, '\0');
281  return (PAPI_OK);
282 }
283 
295 {
296  char *start = NULL;
297 /* We assume ::: is the seperator
298  * eg:
299  * papi_component:::event_name
300  */
301 
302  start = strstr( event_name, ":::" );
303  if ( start != NULL )
304  start+= 3; /* return the actual start of event_name */
305  else
306  start = event_name;
307 
308  return (start);
309 }
310 
311 /* find the papi event code (4000xxx) associated with the specified component, native event, and event name */
312 static int
314  INTDBG("ENTER: cidx: %x, event: %#x, event_name: %s\n", cidx, event, event_name);
315 
316  int i;
317 
318  // if no event name passed in, it can not be found
319  if (event_name == NULL) {
320  INTDBG("EXIT: PAPI_ENOEVNT\n");
321  return PAPI_ENOEVNT;
322  }
323 
324  for(i=0;i<num_native_events;i++) {
325  // if we have have not set up this event name yet, look at next
326  if (_papi_native_events[i].evt_name == NULL) {
327  continue;
328  }
329 
330  // is this entry for the correct component and event code
331  if ((_papi_native_events[i].cidx==cidx) &&
332  (_papi_native_events[i].component_event==event)) {
333  // if this event name matches what we want, return its papi event code
334  if (strcmp(event_name, _papi_native_events[i].evt_name) == 0) {
335  INTDBG("EXIT: event: %#x, component_event: %#x, ntv_idx: %d, event_name: %s\n",
336  i|PAPI_NATIVE_MASK, _papi_native_events[i].component_event, _papi_native_events[i].ntv_idx, _papi_native_events[i].evt_name);
337  return i|PAPI_NATIVE_MASK;
338  }
339  }
340  }
341 
342  INTDBG("EXIT: PAPI_ENOEVNT\n");
343  return PAPI_ENOEVNT;
344 }
345 
346 static int
347 _papi_hwi_add_native_event(int cidx, int ntv_event, int ntv_idx, const char *event_name) {
348  INTDBG("ENTER: cidx: %d, ntv_event: %#x, ntv_idx: %d, event_name: %s\n", cidx, ntv_event, ntv_idx, event_name);
349 
350  int new_native_event;
351 
353 
356  _papi_native_events=realloc(_papi_native_events,
357  num_native_chunks*NATIVE_EVENT_CHUNKSIZE*
358  sizeof(struct native_event_info));
359  if (_papi_native_events==NULL) {
360  new_native_event=PAPI_ENOMEM;
361  goto native_alloc_early_out;
362  }
363  }
364 
365  _papi_native_events[num_native_events].cidx=cidx;
366  _papi_native_events[num_native_events].component_event=ntv_event;
367  _papi_native_events[num_native_events].ntv_idx=ntv_idx;
368  if (event_name != NULL) {
369  _papi_native_events[num_native_events].evt_name=strdup(event_name);
370  } else {
371  _papi_native_events[num_native_events].evt_name=NULL;
372  }
373  new_native_event=num_native_events|PAPI_NATIVE_MASK;
374 
376 
377 native_alloc_early_out:
378 
380 
381  INTDBG("EXIT: new_native_event: %#x, num_native_events: %d\n", new_native_event, num_native_events);
382  return new_native_event;
383 }
384 
391 static int
392 _papi_hwi_add_error( char *error )
393 {
394  INTDBG("Adding a new Error message |%s|\n", error);
396 
399  _papi_errlist=realloc(_papi_errlist,
400  num_error_chunks*NATIVE_EVENT_CHUNKSIZE*sizeof(char *));
401  if (_papi_errlist==NULL) {
403  goto bail;
404  }
405 
406  }
407 
408  _papi_errlist[_papi_hwi_num_errors] = strdup( error );
409  if ( _papi_errlist[_papi_hwi_num_errors] == NULL )
411 
412 bail:
414 
415  return _papi_hwi_num_errors++;
416 }
417 
418 static void
420 {
421  int i;
422 
423  if ( _papi_errlist == NULL ||
424  _papi_hwi_num_errors == 0 )
425  return;
426 
427 
429  for (i=0; i < _papi_hwi_num_errors; i++ ) {
430  free( _papi_errlist[i]);
431  _papi_errlist[i] = NULL;
432  }
433 
434  free( _papi_errlist );
435  _papi_errlist = NULL;
436  _papi_hwi_num_errors = 0;
438 
440 }
441 
442 static int
443 _papi_hwi_lookup_error( char *error )
444 {
445  int i;
446 
447  for (i=0; i<_papi_hwi_num_errors; i++) {
448  if ( !strncasecmp( _papi_errlist[i], error, strlen( error ) ) )
449  return i;
450 
451  }
452 
453  return (-1);
454 }
455 
466 int _papi_hwi_publish_error( char *error )
467 {
468  int error_code = -1;
469 
470  if ( (error_code = _papi_hwi_lookup_error( error )) < 0 )
471  error_code = _papi_hwi_add_error(error);
472 
473  return (-error_code); /* internally error_code is an index, externally, it should be <= 0 */
474 }
475 
476 void
478 /* we use add error to avoid the cost of lookups, we know the errors are not there yet */
479  _papi_hwi_add_error("No error");
480  _papi_hwi_add_error("Invalid argument");
481  _papi_hwi_add_error("Insufficient memory");
482  _papi_hwi_add_error("A System/C library call failed");
483  _papi_hwi_add_error("Not supported by component");
484  _papi_hwi_add_error("Access to the counters was lost or interrupted");
485  _papi_hwi_add_error("Internal error, please send mail to the developers");
486  _papi_hwi_add_error("Event does not exist");
487  _papi_hwi_add_error("Event exists, but cannot be counted due to hardware resource limits");
488  _papi_hwi_add_error("EventSet is currently not running");
489  _papi_hwi_add_error("EventSet is currently counting");
490  _papi_hwi_add_error("No such EventSet available");
491  _papi_hwi_add_error("Event in argument is not a valid preset");
492  _papi_hwi_add_error("Hardware does not support performance counters");
493  _papi_hwi_add_error("Unknown error code");
494  _papi_hwi_add_error("Permission level does not permit operation");
495  _papi_hwi_add_error("PAPI hasn't been initialized yet");
496  _papi_hwi_add_error("Component Index isn't set");
497  _papi_hwi_add_error("Not supported");
498  _papi_hwi_add_error("Not implemented");
499  _papi_hwi_add_error("Buffer size exceeded");
500  _papi_hwi_add_error("EventSet domain is not supported for the operation");
501  _papi_hwi_add_error("Invalid or missing event attributes");
502  _papi_hwi_add_error("Too many events or attributes");
503  _papi_hwi_add_error("Bad combination of features");
504 }
505 
506 int
508 {
509  return ( cidx < 0 || cidx >= papi_num_components );
510 }
511 
512 
513 int
514 _papi_hwi_component_index( int event_code ) {
515  INTDBG("ENTER: event_code: %#x\n", event_code);
516 
517  int cidx;
518  int event_index;
519 
520  /* currently assume presets are for component 0 only */
521  if (event_code&PAPI_PRESET_MASK) {
522  INTDBG("EXIT: Event %#x is a PRESET, assigning component %d\n", event_code,0);
523  return 0;
524  }
525 
526  event_index=event_code&PAPI_NATIVE_AND_MASK;
527 
528  if ( (event_index < 0) || (event_index>=num_native_events)) {
529  INTDBG("EXIT: Event index %#x is out of range, num_native_events: %d\n", event_index, num_native_events);
530  return PAPI_ENOEVNT;
531  }
532 
533  cidx=_papi_native_events[event_index].cidx;
534 
535  if ((cidx<0) || (cidx >= papi_num_components)) {
536  INTDBG("EXIT: Component index %#x is out of range, papi_num_components: %d\n", cidx, papi_num_components);
537  return PAPI_ENOCMP;
538  }
539 
540  INTDBG("EXIT: Found cidx: %d event_index: %d, event_code: %#x\n", cidx, event_index, event_code);
541  return cidx;
542 }
543 
544 /* Convert an internal component event to a papi event code */
545 int
546 _papi_hwi_native_to_eventcode(int cidx, int event_code, int ntv_idx, const char *event_name) {
547  INTDBG("Entry: cidx: %d, event: %#x, ntv_idx: %d, event_name: %s\n", cidx, event_code, ntv_idx, event_name);
548 
549  int result;
550 
551  if (papi_event_code_changed > 0) {
553  INTDBG("EXIT: papi_event_code: %#x set by the component\n", result);
554  return result;
555  }
556 
557  result=_papi_hwi_find_native_event(cidx, event_code, event_name);
558  if (result==PAPI_ENOEVNT) {
559  // Need to create one
560  result=_papi_hwi_add_native_event(cidx, event_code, ntv_idx, event_name);
561  }
562 
563  INTDBG("EXIT: result: %#x\n", result);
564  return result;
565 }
566 
567 /* Convert a native_event code to an internal event code */
568 int
570  INTDBG("ENTER: event_code: %#x\n", event_code);
571 
572  int result;
573  int event_index;
574 
575  event_index=event_code&PAPI_NATIVE_AND_MASK;
576  if (event_index>=num_native_events) {
577  INTDBG("EXIT: PAPI_ENOEVNT\n");
578  return PAPI_ENOEVNT;
579  }
580 
581  result=_papi_native_events[event_index].component_event;
582 
583  INTDBG("EXIT: result: %#x\n", result);
584  return result;
585 
586 }
587 
588 
589 /*********************/
590 /* Utility functions */
591 /*********************/
592 
593 void
594 PAPIERROR( char *format, ... )
595 {
596  va_list args;
597  if ( ( _papi_hwi_error_level != PAPI_QUIET ) ||
598  ( getenv( "PAPI_VERBOSE" ) ) ) {
599  va_start( args, format );
600  fprintf( stderr, "\nPAPI Error: " );
601  vfprintf( stderr, format, args );
602  fprintf( stderr, ".\n" );
603  va_end( args );
604  }
605 }
606 
607 static int
608 default_debug_handler( int errorCode )
609 {
610  char str[PAPI_HUGE_STR_LEN];
611 
612  if ( errorCode == PAPI_OK )
613  return ( errorCode );
614  if ( ( errorCode > 0 ) || ( -errorCode > _papi_hwi_num_errors ) ) {
615  PAPIERROR( "%s %d,%s,Bug! Unknown error code", PAPI_ERROR_CODE_str,
616  errorCode, "" );
617  return ( PAPI_EBUG );
618  }
619 
620  switch ( _papi_hwi_error_level ) {
621  case PAPI_VERB_ECONT:
622  case PAPI_VERB_ESTOP:
623  /* gcc 2.96 bug fix, do not change */
624  /* fprintf(stderr,"%s %d: %s: %s\n",PAPI_ERROR_CODE_str,errorCode,_papi_hwi_err[-errorCode].name,_papi_hwi_err[-errorCode].descr); */
625 
626  sprintf( str, "%s %d,%s", PAPI_ERROR_CODE_str, errorCode,
627  _papi_errlist[-errorCode] );
628  if ( errorCode == PAPI_ESYS )
629  sprintf( str + strlen( str ), ": %s", strerror( errno ) );
630 
631  PAPIERROR( str );
632 
634  abort( ); /* patch provided by will cohen of redhat */
635  else
636  return errorCode;
637  break;
638 
639  case PAPI_QUIET:
640  default:
641  return errorCode;
642  }
643  return ( PAPI_EBUG ); /* Never get here */
644 }
645 
646 static int
648 {
649  /* Allocate and clear the Dynamic Array structure */
650  if ( map->dataSlotArray != NULL )
651  papi_free( map->dataSlotArray );
652  memset( map, 0x00, sizeof ( DynamicArray_t ) );
653 
654  /* Allocate space for the EventSetInfo_t pointers */
655 
656  map->dataSlotArray =
658  sizeof ( EventSetInfo_t * ) );
659  if ( map->dataSlotArray == NULL ) {
660  return ( PAPI_ENOMEM );
661  }
662  memset( map->dataSlotArray, 0x00,
666  map->fullSlots = 0;
667 
668  return ( PAPI_OK );
669 }
670 
671 static int
673 {
674  int number;
675  EventSetInfo_t **n;
676 
677  /*realloc existing PAPI_EVENTSET_MAP.dataSlotArray */
678 
679  number = DA->totalSlots * 2;
680  n = ( EventSetInfo_t ** ) papi_realloc( DA->dataSlotArray,
681  ( size_t ) number *
682  sizeof ( EventSetInfo_t * ) );
683  if ( n == NULL )
684  return ( PAPI_ENOMEM );
685 
686  /* Need to assign this value, what if realloc moved it? */
687 
688  DA->dataSlotArray = n;
689 
690  memset( DA->dataSlotArray + DA->totalSlots, 0x00,
691  ( size_t ) DA->totalSlots * sizeof ( EventSetInfo_t * ) );
692 
693  DA->totalSlots = number;
694  DA->availSlots = number - DA->fullSlots;
695 
696  return ( PAPI_OK );
697 }
698 
699 static int
701 {
702  return ( _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs );
703 }
704 
705 
706 
707 
708 
709 /*========================================================================*/
710 /* This function allocates space for one EventSetInfo_t structure and for */
711 /* all of the pointers in this structure. If any malloc in this function */
712 /* fails, all memory malloced to the point of failure is freed, and NULL */
713 /* is returned. Upon success, a pointer to the EventSetInfo_t data */
714 /* structure is returned. */
715 /*========================================================================*/
716 
717 
718 static int
720 {
721  EventSetInfo_t *ESI;
722 
723  ESI = ( EventSetInfo_t * ) papi_calloc( 1, sizeof ( EventSetInfo_t ) );
724  if ( ESI == NULL ) {
725  return PAPI_ENOMEM;
726  }
727 
728  *here = ESI;
729 
730  return PAPI_OK;
731 }
732 
733 int
735 {
736  int retval;
737  size_t max_counters;
738  char *ptr;
739  unsigned int i, j;
740 
741  /* If component doesn't exist... */
742  if (_papi_hwi_invalid_cmp(cidx)) return PAPI_ECMP;
743 
744  /* Assigned at create time */
746  ESI->granularity.granularity =
748  ESI->CmpIdx = cidx;
749 
750  /* ??? */
751  max_counters = ( size_t ) _papi_hwd[cidx]->cmp_info.num_mpx_cntrs;
752 
753  ESI->ctl_state = (hwd_control_state_t *) papi_calloc( 1, (size_t)
754  _papi_hwd[cidx]->size.control_state );
755  ESI->sw_stop = (long long *) papi_calloc( ( size_t ) max_counters,
756  sizeof ( long long ) );
757  ESI->hw_start = ( long long * ) papi_calloc( ( size_t ) max_counters,
758  sizeof ( long long ) );
759  ESI->EventInfoArray = ( EventInfo_t * ) papi_calloc( (size_t) max_counters,
760  sizeof ( EventInfo_t ) );
761 
762  /* allocate room for the native events and for the component-private */
763  /* register structures */
764  /* ugh is there a cleaner way to allocate this? vmw */
765  ESI->NativeInfoArray = ( NativeInfo_t * )
766  papi_calloc( ( size_t ) max_counters, sizeof ( NativeInfo_t ));
767 
768  ESI->NativeBits = papi_calloc(( size_t ) max_counters,
769  ( size_t ) _papi_hwd[cidx]->size.reg_value );
770 
771  /* NOTE: the next two malloc allocate blocks of memory that are later */
772  /* parcelled into overflow and profile arrays */
773  ESI->overflow.deadline = ( long long * )
774  papi_malloc( ( sizeof ( long long ) +
775  sizeof ( int ) * 3 ) * ( size_t ) max_counters );
776 
777  ESI->profile.prof = ( PAPI_sprofil_t ** )
778  papi_malloc( ( sizeof ( PAPI_sprofil_t * ) * ( size_t ) max_counters +
779  ( size_t ) max_counters * sizeof ( int ) * 4 ) );
780 
781  /* If any of these allocations failed, free things up and fail */
782 
783  if ( ( ESI->ctl_state == NULL ) ||
784  ( ESI->sw_stop == NULL ) ||
785  ( ESI->hw_start == NULL ) ||
786  ( ESI->NativeInfoArray == NULL ) ||
787  ( ESI->NativeBits == NULL ) ||
788  ( ESI->EventInfoArray == NULL ) ||
789  ( ESI->profile.prof == NULL ) ||
790  ( ESI->overflow.deadline == NULL ) ) {
791 
792  if ( ESI->sw_stop ) papi_free( ESI->sw_stop );
793  if ( ESI->hw_start ) papi_free( ESI->hw_start );
794  if ( ESI->EventInfoArray ) papi_free( ESI->EventInfoArray );
795  if ( ESI->NativeInfoArray ) papi_free( ESI->NativeInfoArray );
796  if ( ESI->NativeBits ) papi_free( ESI->NativeBits );
797  if ( ESI->ctl_state ) papi_free( ESI->ctl_state );
798  if ( ESI->overflow.deadline ) papi_free( ESI->overflow.deadline );
799  if ( ESI->profile.prof ) papi_free( ESI->profile.prof );
800  papi_free( ESI );
801  return PAPI_ENOMEM;
802  }
803 
804 
805  /* Carve up the overflow block into separate arrays */
806  ptr = ( char * ) ESI->overflow.deadline;
807  ptr += sizeof ( long long ) * max_counters;
808  ESI->overflow.threshold = ( int * ) ptr;
809  ptr += sizeof ( int ) * max_counters;
810  ESI->overflow.EventIndex = ( int * ) ptr;
811  ptr += sizeof ( int ) * max_counters;
812  ESI->overflow.EventCode = ( int * ) ptr;
813 
814  /* Carve up the profile block into separate arrays */
815  ptr = ( char * ) ESI->profile.prof +
816  ( sizeof ( PAPI_sprofil_t * ) * max_counters );
817  ESI->profile.count = ( int * ) ptr;
818  ptr += sizeof ( int ) * max_counters;
819  ESI->profile.threshold = ( int * ) ptr;
820  ptr += sizeof ( int ) * max_counters;
821  ESI->profile.EventIndex = ( int * ) ptr;
822  ptr += sizeof ( int ) * max_counters;
823  ESI->profile.EventCode = ( int * ) ptr;
824 
825  /* initialize_EventInfoArray */
826 
827  for ( i = 0; i < max_counters; i++ ) {
828  ESI->EventInfoArray[i].event_code=( unsigned int ) PAPI_NULL;
829  ESI->EventInfoArray[i].ops = NULL;
831  for ( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ ) {
832  ESI->EventInfoArray[i].pos[j] = PAPI_NULL;
833  }
834  }
835 
836  /* initialize_NativeInfoArray */
837  for( i = 0; i < max_counters; i++ ) {
838  ESI->NativeInfoArray[i].ni_event = -1;
839  ESI->NativeInfoArray[i].ni_position = -1;
840  ESI->NativeInfoArray[i].ni_papi_code = -1;
841  ESI->NativeInfoArray[i].ni_owners = 0;
842  ESI->NativeInfoArray[i].ni_bits = ((unsigned char*)ESI->NativeBits) +
844  }
845 
846  ESI->NativeCount = 0;
847 
848  ESI->state = PAPI_STOPPED;
849 
850  /* these used to be init_config */
851  retval = _papi_hwd[cidx]->init_control_state( ESI->ctl_state );
852  retval |= _papi_hwd[cidx]->set_domain( ESI->ctl_state, ESI->domain.domain);
853 
854  return retval;
855 }
856 
857 /*========================================================================*/
858 /* This function should free memory for one EventSetInfo_t structure. */
859 /* The argument list consists of a pointer to the EventSetInfo_t */
860 /* structure, *ESI. */
861 /* The calling function should check for ESI==NULL. */
862 /*========================================================================*/
863 
864 void
866 {
868 
869 #ifdef DEBUG
870  memset( ESI, 0x00, sizeof ( EventSetInfo_t ) );
871 #endif
872  papi_free( ESI );
873 
874 }
875 
876 static int
878 {
879  DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
880  int i, errorCode;
881 
883 
884  if ( map->availSlots == 0 ) {
885  errorCode = expand_dynamic_array( map );
886  if ( errorCode < PAPI_OK ) {
888  return ( errorCode );
889  }
890  }
891 
892  i = 0;
893  for ( i = 0; i < map->totalSlots; i++ ) {
894  if ( map->dataSlotArray[i] == NULL ) {
895  ESI->master = master;
896  ESI->EventSetIndex = i;
897  map->fullSlots++;
898  map->availSlots--;
899  map->dataSlotArray[i] = ESI;
901  return ( PAPI_OK );
902  }
903  }
904 
906  return ( PAPI_EBUG );
907 }
908 
909 int
911 {
912  EventSetInfo_t *ESI;
913  int retval;
914 
915  /* Is the EventSet already in existence? */
916 
917  if ( ( EventSet == NULL ) || ( handle == NULL ) )
918  return PAPI_EINVAL;
919 
920  if ( *EventSet != PAPI_NULL )
921  return PAPI_EINVAL;
922 
923  /* Well, then allocate a new one. Use n to keep track of a NEW EventSet */
924 
925  retval = create_EventSet( &ESI );
926  if ( retval != PAPI_OK )
927  return retval;
928 
929  ESI->CmpIdx = -1; /* when eventset is created, it is not decided yet which component it belongs to, until first event is added */
930  ESI->state = PAPI_STOPPED;
931 
932  /* Add it to the global table */
933 
934  retval = add_EventSet( ESI, handle );
935  if ( retval < PAPI_OK ) {
937  return retval ;
938  }
939 
940  *EventSet = ESI->EventSetIndex;
941 
942  INTDBG( "(%p,%p): new EventSet in slot %d\n",
943  ( void * ) EventSet, handle, *EventSet );
944 
945  return retval;
946 }
947 
948 /* This function returns the index of the the next free slot
949  in the EventInfoArray. If EventCode is already in the list,
950  it returns PAPI_ECNFLCT. */
951 
952 static int
953 get_free_EventCodeIndex( const EventSetInfo_t * ESI, unsigned int EventCode )
954 {
955  int k;
956  int lowslot = PAPI_ECNFLCT;
957  int limit = EventInfoArrayLength( ESI );
958 
959  /* Check for duplicate events and get the lowest empty slot */
960 
961  for ( k = 0; k < limit; k++ ) {
962  if ( ESI->EventInfoArray[k].event_code == EventCode )
963  return ( PAPI_ECNFLCT );
964  /*if ((ESI->EventInfoArray[k].event_code == PAPI_NULL) && (lowslot == PAPI_ECNFLCT)) */
965  if ( ESI->EventInfoArray[k].event_code == ( unsigned int ) PAPI_NULL ) {
966  lowslot = k;
967  break;
968  }
969  }
970  return ( lowslot );
971 }
972 
973 /* This function returns the index of the EventCode or error */
974 /* Index to what? The index to everything stored EventCode in the */
975 /* EventSet. */
976 
977 int
979  unsigned int EventCode )
980 {
981  int i;
982  int limit = EventInfoArrayLength( ESI );
983 
984  for ( i = 0; i < limit; i++ ) {
985  if ( ESI->EventInfoArray[i].event_code == EventCode ) {
986  return i;
987  }
988  }
989 
990  return PAPI_EINVAL;
991 }
992 
993 /* This function only removes empty EventSets */
994 
995 int
997 {
998  DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
999  int i;
1000 
1001  i = ESI->EventSetIndex;
1002 
1004 
1005  _papi_hwi_free_EventSet( ESI );
1006 
1007  /* do bookkeeping for PAPI_EVENTSET_MAP */
1008 
1009  map->dataSlotArray[i] = NULL;
1010  map->availSlots++;
1011  map->fullSlots--;
1012 
1014 
1015  return PAPI_OK;
1016 }
1017 
1018 
1019 /* this function checks if an event is already in an EventSet
1020  Success, return ESI->NativeInfoArray[] index
1021  Fail, return PAPI_ENOEVNT;
1022 */
1023 static int
1025 {
1026  INTDBG( "ENTER: ESI: %p, papi_event: %#x\n", ESI, papi_event);
1027  int i;
1028 
1029  int nevt = _papi_hwi_eventcode_to_native(papi_event);
1030 
1031  /* to find the native event from the native events list */
1032  for( i = 0; i < ESI->NativeCount; i++ ) {
1033  if ( nevt == ESI->NativeInfoArray[i].ni_event ) {
1034  // Also need to check papi event code if set because the same event with different masks
1035  // will generate the same libpfm4 event code (what was checked above). But there will be
1036  // different papi events created for it and they need to be handled separately.
1037  if (papi_event == ESI->NativeInfoArray[i].ni_papi_code) {
1038  INTDBG( "EXIT: event: %#x already mapped at index: %d\n", papi_event, i);
1039  return i;
1040  }
1041  }
1042  }
1043  INTDBG( "EXIT: PAPI_ENOEVNT\n");
1044  return PAPI_ENOEVNT;
1045 }
1046 
1047 /* This function goes through the events in an EventSet's EventInfoArray */
1048 /* And maps each event (whether native or part of a preset) to */
1049 /* an event in the EventSets NativeInfoArray. */
1050 
1051 /* We need to do this every time a native event is added to or removed */
1052 /* from an eventset. */
1053 
1054 /* It is also called after a update controlstate as the components are */
1055 /* allowed to re-arrange the native events to fit hardware constraints. */
1056 
1057 void
1059 {
1060  INTDBG("ENTER: ESI: %p, ESI->EventInfoArray: %p, ESI->NativeInfoArray: %p, ESI->NumberOfEvents: %d, ESI->NativeCount: %d\n", ESI, ESI->EventInfoArray, ESI->NativeInfoArray, ESI->NumberOfEvents, ESI->NativeCount);
1061 
1062  int i, event, k, n, preset_index = 0, nevt;
1063  int total_events = ESI->NumberOfEvents;
1064 
1065  event = 0;
1066  for( i = 0; i < total_events; i++ ) {
1067 
1068  /* find the first event that isn't PAPI_NULL */
1069  /* Is this really necessary? --vmw */
1070  while ( ESI->EventInfoArray[event].event_code == ( unsigned int ) PAPI_NULL ) {
1071  event++;
1072  }
1073 
1074  /* If it's a preset */
1075  if ( IS_PRESET(ESI->EventInfoArray[event].event_code) ) {
1076  preset_index = ( int ) ESI->EventInfoArray[event].event_code & PAPI_PRESET_AND_MASK;
1077 
1078  /* walk all sub-events in the preset */
1079  for( k = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT; k++ ) {
1080  nevt = _papi_hwi_presets[preset_index].code[k];
1081  if ( nevt == PAPI_NULL ) {
1082  break;
1083  }
1084 
1085  INTDBG("Looking for subevent %#x\n",nevt);
1086 
1087  /* Match each sub-event to something in the Native List */
1088  for( n = 0; n < ESI->NativeCount; n++ ) {
1089  if ( nevt == ESI->NativeInfoArray[n].ni_papi_code ) {
1090  INTDBG("Found papi event: %#x, &ESI->NativeInfoArray[%d]: %p, ni_event: %#x, ni_position %d\n",
1091  nevt, n, &(ESI->NativeInfoArray[n]), ESI->NativeInfoArray[n].ni_event, ESI->NativeInfoArray[n].ni_position);
1093  break;
1094  }
1095  }
1096  }
1097  }
1098  /* It's a native event */
1099  else if( IS_NATIVE(ESI->EventInfoArray[event].event_code) ) {
1100  nevt = ( int ) ESI->EventInfoArray[event].event_code;
1101 
1102  // get index into native info array for this event
1103  int nidx = event_already_in_eventset( ESI, nevt );
1104  // if not found, then we need to return an error
1105  if (nidx == PAPI_ENOEVNT) {
1106  INTDBG("EXIT: needed event not found\n");
1107  return;
1108  }
1109  ESI->EventInfoArray[event].pos[0] = ESI->NativeInfoArray[nidx].ni_position;
1110  INTDBG("nidx: %d, ni_position: %d\n", nidx, ESI->NativeInfoArray[nidx].ni_position);
1111 
1112  /* It's a user-defined event */
1113  } else if ( IS_USER_DEFINED(ESI->EventInfoArray[event].event_code) ) {
1114  for ( k = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT; k++ ) {
1115  nevt = _papi_user_events[preset_index].events[k];
1116  if ( nevt == PAPI_NULL ) break;
1117 
1118  /* Match each sub-event to something in the Native List */
1119  for ( n = 0; n < ESI->NativeCount; n++ ) {
1120  if ( _papi_hwi_eventcode_to_native(nevt) == ESI->NativeInfoArray[n].ni_event ) {
1122  }
1123  }
1124  }
1125  }
1126  event++;
1127  }
1128 }
1129 
1130 
1131 static int
1133 {
1134  INTDBG("ENTER: ESI: %p, nevt: %#x\n", ESI, nevt);
1135 
1136  int i, max_counters;
1137  int cidx;
1138 
1139  cidx = _papi_hwi_component_index( nevt );
1140  if (cidx<0) return PAPI_ENOCMP;
1141 
1142  max_counters = _papi_hwd[cidx]->cmp_info.num_mpx_cntrs;
1143 
1144  /* to find the native event from the native events list */
1145  for( i = 0; i < max_counters; i++ ) {
1146 // INTDBG("ESI->NativeInfoArray[%d]: %p, ni_event: %#x, ni_papi_event_code: %#x, ni_position: %d, ni_owners: %d\n",
1147 // i, &(ESI->NativeInfoArray[i]), ESI->NativeInfoArray[i].ni_event, ESI->NativeInfoArray[i].ni_papi_code, ESI->NativeInfoArray[i].ni_position, ESI->NativeInfoArray[i].ni_owners);
1148  if ( nevt == ESI->NativeInfoArray[i].ni_papi_code ) {
1149  ESI->NativeInfoArray[i].ni_owners--;
1150  /* to clean the entry in the nativeInfo array */
1151  if ( ESI->NativeInfoArray[i].ni_owners == 0 ) {
1152  ESI->NativeInfoArray[i].ni_event = -1;
1153  ESI->NativeInfoArray[i].ni_position = -1;
1154  ESI->NativeInfoArray[i].ni_papi_code = -1;
1155  ESI->NativeCount--;
1156  }
1157  INTDBG( "EXIT: nevt: %#x, returned: %d\n", nevt, i);
1158  return i;
1159  }
1160  }
1161  INTDBG( "EXIT: returned: -1\n");
1162  return -1;
1163 }
1164 
1165 /* since update_control_state trashes overflow settings, this puts things
1166  back into balance. */
1167 static int
1169 {
1170  int i, retval = PAPI_OK;
1171 
1172  if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
1173  for( i = 0; i < ESI->overflow.event_counter; i++ ) {
1174  retval = _papi_hwd[ESI->CmpIdx]->set_overflow( ESI,
1175  ESI->overflow.EventIndex[i],
1176  ESI->overflow.threshold[i] );
1177  if ( retval != PAPI_OK ) {
1178  break;
1179  }
1180  }
1181  }
1182  return retval;
1183 }
1184 
1185 /* this function is called by _papi_hwi_add_event when adding native events
1186  ESI: event set to add the events to
1187  nevnt: pointer to array of native event table indexes to add
1188  size: number of native events to add
1189  out: ???
1190 
1191  return: < 0 = error
1192  0 = no new events added
1193  1 = new events added
1194 */
1195 static int
1196 add_native_events( EventSetInfo_t *ESI, unsigned int *nevt,
1197  int size, EventInfo_t *out )
1198 {
1199  INTDBG ("ENTER: ESI: %p, nevt: %p, size: %d, out: %p\n", ESI, nevt, size, out);
1200  int nidx, i, j, added_events = 0;
1201  int retval, retval2;
1202  int max_counters;
1203  hwd_context_t *context;
1204 
1205  max_counters = _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs;
1206 
1207  /* Walk through the list of native events, adding them */
1208  for( i = 0; i < size; i++ ) {
1209 
1210  /* Check to see if event is already in EventSet */
1211  nidx = event_already_in_eventset( ESI, nevt[i] );
1212 
1213  if ( nidx >= 0 ) {
1214  /* Event is already there. Set position */
1215  out->pos[i] = ESI->NativeInfoArray[nidx].ni_position;
1216  ESI->NativeInfoArray[nidx].ni_owners++;
1217  continue;
1218  }
1219 
1220  /* Event wasn't already there */
1221 
1222  if ( ESI->NativeCount == max_counters ) {
1223 
1224  /* No more room in counters! */
1225  for( j = 0; j < i; j++ ) {
1226  if ( ( nidx = add_native_fail_clean( ESI, nevt[j] ) ) >= 0 ) {
1227  out->pos[j] = -1;
1228  continue;
1229  }
1230  INTDBG( "should not happen!\n" );
1231  }
1232  INTDBG( "EXIT: counters are full!\n" );
1233  return PAPI_ECOUNT;
1234  }
1235 
1236  /* there is an empty slot for the native event; */
1237  /* initialize the native index for the new added event */
1238  INTDBG( "Adding nevt[%d]: %#x, ESI->NativeInfoArray[%d]: %p, Component: %d\n",
1239  i, nevt[i], ESI->NativeCount, &ESI->NativeInfoArray[ESI->NativeCount], ESI->CmpIdx );
1240  ESI->NativeInfoArray[ESI->NativeCount].ni_event =
1242  ESI->NativeInfoArray[ESI->NativeCount].ni_papi_code = nevt[i];
1243 
1244  ESI->NativeInfoArray[ESI->NativeCount].ni_owners = 1;
1245  ESI->NativeCount++;
1246  added_events++;
1247  }
1248 
1249  INTDBG("added_events: %d\n", added_events);
1250 
1251  /* if we added events we need to tell the component so it */
1252  /* can add them too. */
1253  if ( added_events ) {
1254  /* get the context we should use for this event set */
1255  context = _papi_hwi_get_context( ESI, NULL );
1256 
1257  if ( _papi_hwd[ESI->CmpIdx]->allocate_registers( ESI ) == PAPI_OK ) {
1258 
1259  retval = _papi_hwd[ESI->CmpIdx]->update_control_state( ESI->ctl_state,
1260  ESI->NativeInfoArray,
1261  ESI->NativeCount,
1262  context);
1263  if ( retval != PAPI_OK ) {
1264 clean:
1265  for( i = 0; i < size; i++ ) {
1266  if ( ( nidx = add_native_fail_clean( ESI, nevt[i] ) ) >= 0 ) {
1267  out->pos[i] = -1;
1268  continue;
1269  }
1270  INTDBG( "should not happen!\n" );
1271  }
1272  /* re-establish the control state after the previous error */
1273  retval2 = _papi_hwd[ESI->CmpIdx]->update_control_state(
1274  ESI->ctl_state,
1275  ESI->NativeInfoArray,
1276  ESI->NativeCount,
1277  context);
1278  if ( retval2 != PAPI_OK ) {
1279  PAPIERROR("update_control_state failed to re-establish working events!" );
1280  INTDBG( "EXIT: update_control_state returned: %d\n", retval2);
1281  return retval2;
1282  }
1283  INTDBG( "EXIT: update_control_state returned: %d\n", retval);
1284  return retval;
1285  }
1286  INTDBG( "EXIT: update_control_state returned: %d, we return: 1 (need remap)\n", retval);
1287  return 1; /* need remap */
1288  } else {
1289  retval = PAPI_EMISC;
1290  goto clean;
1291  }
1292  }
1293  INTDBG( "EXIT: PAPI_OK\n");
1294  return PAPI_OK;
1295 }
1296 
1297 
1298 int
1299 _papi_hwi_add_event( EventSetInfo_t * ESI, int EventCode )
1300 {
1301  int i, j, thisindex, remap, retval = PAPI_OK;
1302  int cidx;
1303 
1304  cidx=_papi_hwi_component_index( EventCode );
1305  if (cidx<0) return PAPI_ENOCMP;
1306 
1307  /* Sanity check that the new EventCode is from the same component */
1308  /* as previous events. */
1309 
1310  if ( ESI->CmpIdx < 0 ) {
1311  if ( ( retval = _papi_hwi_assign_eventset( ESI, cidx)) != PAPI_OK ) {
1312  return retval;
1313  }
1314  } else {
1315  if ( ESI->CmpIdx != cidx ) {
1316  return PAPI_EINVAL;
1317  }
1318  }
1319 
1320  /* Make sure the event is not present and get the next free slot. */
1321  thisindex = get_free_EventCodeIndex( ESI, ( unsigned int ) EventCode );
1322  if ( thisindex < PAPI_OK ) {
1323  return thisindex;
1324  }
1325 
1326  INTDBG("Adding event to slot %d of EventSet %d\n",thisindex,ESI->EventSetIndex);
1327 
1328  /* If it is a software MPX EventSet, add it to the multiplex data structure */
1329  /* and this thread's multiplex list */
1330 
1331  if ( !_papi_hwi_is_sw_multiplex( ESI ) ) {
1332 
1333  /* Handle preset case */
1334  if ( IS_PRESET(EventCode) ) {
1335  int count;
1336  int preset_index = EventCode & ( int ) PAPI_PRESET_AND_MASK;
1337 
1338  /* Check if it's within the valid range */
1339  if ( ( preset_index < 0 ) || ( preset_index >= PAPI_MAX_PRESET_EVENTS ) ) {
1340  return PAPI_EINVAL;
1341  }
1342 
1343  /* count the number of native events in this preset */
1344  count = ( int ) _papi_hwi_presets[preset_index].count;
1345 
1346  /* Check if event exists */
1347  if ( !count ) {
1348  return PAPI_ENOEVNT;
1349  }
1350 
1351  /* check if the native events have been used as overflow events */
1352  /* this is not allowed */
1353  if ( ESI->state & PAPI_OVERFLOWING ) {
1354  for( i = 0; i < count; i++ ) {
1355  for( j = 0; j < ESI->overflow.event_counter; j++ ) {
1356  if ( ESI->overflow.EventCode[j] ==(int)
1357  ( _papi_hwi_presets[preset_index].code[i] ) ) {
1358  return PAPI_ECNFLCT;
1359  }
1360  }
1361  }
1362  }
1363 
1364  /* Try to add the preset. */
1365 
1366  remap = add_native_events( ESI,
1367  _papi_hwi_presets[preset_index].code,
1368  count, &ESI->EventInfoArray[thisindex] );
1369  if ( remap < 0 ) {
1370  return remap;
1371  }
1372  else {
1373  /* Fill in the EventCode (machine independent) information */
1374  ESI->EventInfoArray[thisindex].event_code =
1375  ( unsigned int ) EventCode;
1376  ESI->EventInfoArray[thisindex].derived =
1377  _papi_hwi_presets[preset_index].derived_int;
1378  ESI->EventInfoArray[thisindex].ops =
1379  _papi_hwi_presets[preset_index].postfix;
1380  ESI->NumberOfEvents++;
1382 
1383  }
1384  }
1385  /* Handle adding Native events */
1386  else if ( IS_NATIVE(EventCode) ) {
1387 
1388  /* Check if native event exists */
1389  if ( _papi_hwi_query_native_event( ( unsigned int ) EventCode ) != PAPI_OK ) {
1390  return PAPI_ENOEVNT;
1391  }
1392 
1393  /* check if the native events have been used as overflow events */
1394  /* This is not allowed */
1395  if ( ESI->state & PAPI_OVERFLOWING ) {
1396  for( j = 0; j < ESI->overflow.event_counter; j++ ) {
1397  if ( EventCode == ESI->overflow.EventCode[j] ) {
1398  return PAPI_ECNFLCT;
1399  }
1400  }
1401  }
1402 
1403  /* Try to add the native event. */
1404 
1405  remap = add_native_events( ESI, (unsigned int *)&EventCode, 1,
1406  &ESI->EventInfoArray[thisindex] );
1407 
1408  if ( remap < 0 ) {
1409  return remap;
1410  } else {
1411 
1412  /* Fill in the EventCode (machine independent) information */
1413  ESI->EventInfoArray[thisindex].event_code =
1414  ( unsigned int ) EventCode;
1415  ESI->NumberOfEvents++;
1417 
1418  }
1419  } else if ( IS_USER_DEFINED( EventCode ) ) {
1420  int count;
1421  int index = EventCode & PAPI_UE_AND_MASK;
1422 
1423  if ( index < 0 || index >= (int)_papi_user_events_count )
1424  return ( PAPI_EINVAL );
1425 
1426  count = ( int ) _papi_user_events[index].count;
1427 
1428  for ( i = 0; i < count; i++ ) {
1429  for ( j = 0; j < ESI->overflow.event_counter; j++ ) {
1430  if ( ESI->overflow.EventCode[j] ==
1431  _papi_user_events[index].events[i] ) {
1432  return ( PAPI_EBUG );
1433  }
1434  }
1435  }
1436 
1437  remap = add_native_events( ESI,
1438  (unsigned int*)_papi_user_events[index].events,
1439  count, &ESI->EventInfoArray[thisindex] );
1440 
1441  if ( remap < 0 ) {
1442  return remap;
1443  } else {
1444  ESI->EventInfoArray[thisindex].event_code
1445  = (unsigned int) EventCode;
1446  ESI->EventInfoArray[thisindex].derived
1447  = DERIVED_POSTFIX;
1448  ESI->EventInfoArray[thisindex].ops
1449  = _papi_user_events[index].operation;
1450  ESI->NumberOfEvents++;
1452  }
1453  } else {
1454 
1455  /* not Native, Preset, or User events */
1456 
1457  return PAPI_EBUG;
1458  }
1459  }
1460  else {
1461 
1462  /* Multiplexing is special. See multiplex.c */
1463 
1464  retval = mpx_add_event( &ESI->multiplex.mpx_evset, EventCode,
1465  ESI->domain.domain,
1466  ESI->granularity.granularity );
1467 
1468 
1469  if ( retval < PAPI_OK ) {
1470  return retval;
1471  }
1472 
1473  /* Relevant (???) */
1474  ESI->EventInfoArray[thisindex].event_code = ( unsigned int ) EventCode;
1475  ESI->EventInfoArray[thisindex].derived = NOT_DERIVED;
1476 
1477  ESI->NumberOfEvents++;
1478 
1479  /* event is in the EventInfoArray but not mapped to the NativeEvents */
1480  /* this causes issues if you try to set overflow on the event. */
1481  /* in theory this wouldn't matter anyway. */
1482  }
1483 
1484  /* reinstate the overflows if any */
1485  retval=update_overflow( ESI );
1486 
1487  return retval;
1488 }
1489 
1490 static int
1492 {
1493  INTDBG( "Entry: ESI: %p, nevt: %p, size: %d\n", ESI, nevt, size);
1495  hwd_context_t *context;
1496  int i, j, zero = 0, retval;
1497 
1498  /* Remove the references to this event from the native events:
1499  for all the metrics in this event,
1500  compare to each native event in this event set,
1501  and decrement owners if they match */
1502  for( i = 0; i < size; i++ ) {
1503  int cevt = _papi_hwi_eventcode_to_native(nevt[i]);
1504 // INTDBG( "nevt[%d]: %#x, cevt: %#x\n", i, nevt[i], cevt);
1505  for( j = 0; j < ESI->NativeCount; j++ ) {
1506  if ((native[j].ni_event == cevt) && (native[j].ni_papi_code == nevt[i]) ) {
1507 // INTDBG( "native[%d]: %p, ni_papi_code: %#x, ni_event: %#x, ni_position: %d, ni_owners: %d\n",
1508 // j, &(native[j]), native[j].ni_papi_code, native[j].ni_event, native[j].ni_position, native[j].ni_owners);
1509  native[j].ni_owners--;
1510  if ( native[j].ni_owners == 0 ) {
1511  zero++;
1512  }
1513  break;
1514  }
1515  }
1516  }
1517 
1518  /* Remove any native events from the array if owners dropped to zero.
1519  The NativeInfoArray must be dense, with no empty slots, so if we
1520  remove an element, we must compact the list */
1521  for( i = 0; i < ESI->NativeCount; i++ ) {
1522 
1523  if ( native[i].ni_event == -1 ) continue;
1524 
1525  if ( native[i].ni_owners == 0 ) {
1526  int copy = 0;
1527  int sz = _papi_hwd[ESI->CmpIdx]->size.reg_value;
1528  for( j = ESI->NativeCount - 1; j > i; j-- ) {
1529  if ( native[j].ni_event == -1 || native[j].ni_owners == 0 ) continue;
1530  else {
1531  /* copy j into i */
1532  native[i].ni_event = native[j].ni_event;
1533  native[i].ni_position = native[j].ni_position;
1534  native[i].ni_owners = native[j].ni_owners;
1535  /* copy opaque [j].ni_bits to [i].ni_bits */
1536  memcpy( native[i].ni_bits, native[j].ni_bits, ( size_t ) sz );
1537  /* reset j to initialized state */
1538  native[j].ni_event = -1;
1539  native[j].ni_position = -1;
1540  native[j].ni_owners = 0;
1541  copy++;
1542  break;
1543  }
1544  }
1545 
1546  if ( copy == 0 ) {
1547  /* set this structure back to empty state */
1548  /* ni_owners is already 0 and contents of ni_bits doesn't matter */
1549  native[i].ni_event = -1;
1550  native[i].ni_position = -1;
1551  }
1552  }
1553  }
1554 
1555  INTDBG( "ESI->NativeCount: %d, zero: %d\n", ESI->NativeCount, zero);
1556 
1557  /* to reset hwd_control_state values */
1558  ESI->NativeCount -= zero;
1559 
1560  /* If we removed any elements,
1561  clear the now empty slots, reinitialize the index, and update the count.
1562  Then send the info down to the component to update the hwd control structure. */
1563  retval = PAPI_OK;
1564  if ( zero ) {
1565  /* get the context we should use for this event set */
1566  context = _papi_hwi_get_context( ESI, NULL );
1568  native, ESI->NativeCount, context);
1569  if ( retval == PAPI_OK )
1570  retval = update_overflow( ESI );
1571  }
1572  return ( retval );
1573 }
1574 
1575 int
1577 {
1578  int j = 0, retval, thisindex;
1579  EventInfo_t *array;
1580 
1581  thisindex =
1582  _papi_hwi_lookup_EventCodeIndex( ESI, ( unsigned int ) EventCode );
1583  if ( thisindex < PAPI_OK )
1584  return ( thisindex );
1585 
1586  /* If it is a MPX EventSet, remove it from the multiplex data structure and
1587  this threads multiplex list */
1588 
1589  if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
1590  retval = mpx_remove_event( &ESI->multiplex.mpx_evset, EventCode );
1591  if ( retval < PAPI_OK )
1592  return ( retval );
1593  } else
1594  /* Remove the events hardware dependent stuff from the EventSet */
1595  {
1596  if ( IS_PRESET(EventCode) ) {
1597  int preset_index = EventCode & PAPI_PRESET_AND_MASK;
1598 
1599  /* Check if it's within the valid range */
1600  if ( ( preset_index < 0 ) ||
1601  ( preset_index >= PAPI_MAX_PRESET_EVENTS ) )
1602  return PAPI_EINVAL;
1603 
1604  /* Check if event exists */
1605  if ( !_papi_hwi_presets[preset_index].count )
1606  return PAPI_ENOEVNT;
1607 
1608  /* Remove the preset event. */
1609  for ( j = 0; _papi_hwi_presets[preset_index].code[j] != (unsigned int)PAPI_NULL;
1610  j++ );
1612  (int *)_papi_hwi_presets[preset_index].code, j );
1613  if ( retval != PAPI_OK )
1614  return ( retval );
1615  } else if ( IS_NATIVE(EventCode) ) {
1616  /* Check if native event exists */
1617  if ( _papi_hwi_query_native_event( ( unsigned int ) EventCode ) !=
1618  PAPI_OK )
1619  return PAPI_ENOEVNT;
1620 
1621  /* Remove the native event. */
1622  retval = remove_native_events( ESI, &EventCode, 1 );
1623  if ( retval != PAPI_OK )
1624  return ( retval );
1625  } else if ( IS_USER_DEFINED( EventCode ) ) {
1626  int index = EventCode & PAPI_UE_AND_MASK;
1627 
1628  if ( (index < 0) || (index >= (int)_papi_user_events_count) )
1629  return ( PAPI_EINVAL );
1630 
1631  for( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT &&
1632  _papi_user_events[index].events[j] != 0; j++ ) {
1634  _papi_user_events[index].events, j);
1635 
1636  if ( retval != PAPI_OK )
1637  return ( retval );
1638  }
1639  } else
1640  return ( PAPI_ENOEVNT );
1641  }
1642  array = ESI->EventInfoArray;
1643 
1644  /* Compact the Event Info Array list if it's not the last event */
1645  /* clear the newly empty slot in the array */
1646  for ( ; thisindex < ESI->NumberOfEvents - 1; thisindex++ )
1647  array[thisindex] = array[thisindex + 1];
1648 
1649 
1650  array[thisindex].event_code = ( unsigned int ) PAPI_NULL;
1651  for ( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ )
1652  array[thisindex].pos[j] = PAPI_NULL;
1653  array[thisindex].ops = NULL;
1654  array[thisindex].derived = NOT_DERIVED;
1655  ESI->NumberOfEvents--;
1656 
1657  return ( PAPI_OK );
1658 }
1659 
1660 int
1662  long long *values )
1663 {
1664  int retval;
1665  long long *dp = NULL;
1666  int i, index;
1667 
1668  retval = _papi_hwd[ESI->CmpIdx]->read( context, ESI->ctl_state,
1669  &dp, ESI->state );
1670  if ( retval != PAPI_OK ) {
1671  return retval;
1672  }
1673 
1674  /* This routine distributes hardware counters to software counters in the
1675  order that they were added. Note that the higher level
1676  EventInfoArray[i] entries may not be contiguous because the user
1677  has the right to remove an event.
1678  But if we do compaction after remove event, this function can be
1679  changed.
1680  */
1681 
1682  for ( i = 0; i != ESI->NumberOfEvents; i++ ) {
1683 
1684  index = ESI->EventInfoArray[i].pos[0];
1685 
1686  if ( index == -1 )
1687  continue;
1688 
1689  INTDBG( "ESI->EventInfoArray: %p, pos[%d]: %d, dp[%d]: %lld\n", ESI->EventInfoArray, i, index, index, dp[index] );
1690 
1691  /* If this is not a derived event */
1692 
1693  if ( ESI->EventInfoArray[i].derived == NOT_DERIVED ) {
1694  values[i] = dp[index];
1695  INTDBG( "value: %#llx\n", values[i] );
1696  } else { /* If this is a derived event */
1697  values[i] = handle_derived( &ESI->EventInfoArray[i], dp );
1698 #ifdef DEBUG
1699  if ( values[i] < ( long long ) 0 ) {
1700  INTDBG( "Derived Event is negative!!: %lld\n", values[i] );
1701  }
1702  INTDBG( "derived value: %#llx \n", values[i] );
1703 #endif
1704  }
1705  }
1706 
1707  return PAPI_OK;
1708 }
1709 
1710 int
1712 {
1713  int i, j, num_cntrs, retval;
1714  hwd_context_t *context;
1715  int EventCode;
1717  if ( !_papi_hwi_invalid_cmp( ESI->CmpIdx ) ) {
1718  num_cntrs = _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs;
1719 
1720  for(i=0;i<num_cntrs;i++) {
1721 
1722  EventCode=ESI->EventInfoArray[i].event_code;
1723 
1724  /* skip if event not there */
1725  if ( EventCode == PAPI_NULL ) continue;
1726 
1727  /* If it is a MPX EventSet, remove it from the multiplex */
1728  /* data structure and this thread's multiplex list */
1729 
1730  if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
1731  retval = mpx_remove_event( &ESI->multiplex.mpx_evset, EventCode );
1732  if ( retval < PAPI_OK )
1733  return retval;
1734  } else {
1735 
1736  native = ESI->NativeInfoArray;
1737 
1738  /* clear out ESI->NativeInfoArray */
1739  /* do we really need to do this, seeing as we free() it later? */
1740 
1741  for( j = 0; j < ESI->NativeCount; j++ ) {
1742  native[j].ni_event = -1;
1743  native[j].ni_position = -1;
1744  native[j].ni_owners = 0;
1745  /* native[j].ni_bits?? */
1746  }
1747  }
1748 
1749  /* do we really need to do this, seeing as we free() it later? */
1750  ESI->EventInfoArray[i].event_code= ( unsigned int ) PAPI_NULL;
1751  for( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ ) {
1752  ESI->EventInfoArray[i].pos[j] = PAPI_NULL;
1753  }
1754  ESI->EventInfoArray[i].ops = NULL;
1756  }
1757 
1758  context = _papi_hwi_get_context( ESI, NULL );
1759  /* calling with count of 0 equals a close? */
1760  retval = _papi_hwd[ESI->CmpIdx]->update_control_state( ESI->ctl_state,
1761  NULL, 0, context);
1762  if (retval!=PAPI_OK) {
1763  return retval;
1764  }
1765  }
1766 
1767  ESI->CmpIdx = -1;
1768  ESI->NumberOfEvents = 0;
1769  ESI->NativeCount = 0;
1770 
1771  if ( ( ESI->state & PAPI_MULTIPLEXING ) && ESI->multiplex.mpx_evset )
1772  papi_free( ESI->multiplex.mpx_evset );
1773 
1774  if ( ( ESI->state & PAPI_CPU_ATTACH ) && ESI->CpuInfo )
1776 
1777  if ( ESI->ctl_state )
1778  papi_free( ESI->ctl_state );
1779 
1780  if ( ESI->sw_stop )
1781  papi_free( ESI->sw_stop );
1782 
1783  if ( ESI->hw_start )
1784  papi_free( ESI->hw_start );
1785 
1786  if ( ESI->EventInfoArray )
1787  papi_free( ESI->EventInfoArray );
1788 
1789  if ( ESI->NativeInfoArray )
1790  papi_free( ESI->NativeInfoArray );
1791 
1792  if ( ESI->NativeBits )
1793  papi_free( ESI->NativeBits );
1794 
1795  if ( ESI->overflow.deadline )
1796  papi_free( ESI->overflow.deadline );
1797 
1798  if ( ESI->profile.prof )
1799  papi_free( ESI->profile.prof );
1800 
1801  ESI->ctl_state = NULL;
1802  ESI->sw_stop = NULL;
1803  ESI->hw_start = NULL;
1804  ESI->EventInfoArray = NULL;
1805  ESI->NativeInfoArray = NULL;
1806  ESI->NativeBits = NULL;
1807 
1808  memset( &ESI->domain, 0x0, sizeof(EventSetDomainInfo_t) );
1809  memset( &ESI->granularity, 0x0, sizeof(EventSetGranularityInfo_t) );
1810  memset( &ESI->overflow, 0x0, sizeof(EventSetOverflowInfo_t) );
1811  memset( &ESI->multiplex, 0x0, sizeof(EventSetMultiplexInfo_t) );
1812  memset( &ESI->attach, 0x0, sizeof(EventSetAttachInfo_t) );
1813  memset( &ESI->cpu, 0x0, sizeof(EventSetCpuInfo_t) );
1814  memset( &ESI->profile, 0x0, sizeof(EventSetProfileInfo_t) );
1815  memset( &ESI->inherit, 0x0, sizeof(EventSetInheritInfo_t) );
1816 
1817  ESI->CpuInfo = NULL;
1818 
1819  return PAPI_OK;
1820 }
1821 
1822 int
1824 {
1825  int retval, i, j = 0, *mpxlist = NULL;
1826  EventSetInfo_t *ESI = mpx->ESI;
1827  int flags = mpx->flags;
1828 
1829  /* If there are any events in the EventSet,
1830  convert them to multiplex events */
1831 
1832  if ( ESI->NumberOfEvents ) {
1833 
1834  mpxlist =
1835  ( int * ) papi_malloc( sizeof ( int ) *
1836  ( size_t ) ESI->NumberOfEvents );
1837  if ( mpxlist == NULL )
1838  return ( PAPI_ENOMEM );
1839 
1840  /* Build the args to MPX_add_events(). */
1841 
1842  /* Remember the EventInfoArray can be sparse
1843  and the data can be non-contiguous */
1844 
1845  for ( i = 0; i < EventInfoArrayLength( ESI ); i++ )
1846  if ( ESI->EventInfoArray[i].event_code !=
1847  ( unsigned int ) PAPI_NULL )
1848  mpxlist[j++] = ( int ) ESI->EventInfoArray[i].event_code;
1849 
1850  /* Resize the EventInfo_t array */
1851 
1852  if ( ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex == 0 ) ||
1853  ( ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex ) &&
1854  ( flags & PAPI_MULTIPLEX_FORCE_SW ) ) ) {
1855  retval =
1856  MPX_add_events( &ESI->multiplex.mpx_evset, mpxlist, j,
1857  ESI->domain.domain,
1858  ESI->granularity.granularity );
1859  if ( retval != PAPI_OK ) {
1860  papi_free( mpxlist );
1861  return ( retval );
1862  }
1863  }
1864 
1865  papi_free( mpxlist );
1866  }
1867 
1868  /* Update the state before initialization! */
1869 
1870  ESI->state |= PAPI_MULTIPLEXING;
1871  if ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex &&
1872  ( flags & PAPI_MULTIPLEX_FORCE_SW ) )
1874  ESI->multiplex.ns = ( int ) mpx->ns;
1875 
1876  return ( PAPI_OK );
1877 }
1878 
1879 #include "components_config.h"
1880 
1881 int papi_num_components = ( sizeof ( _papi_hwd ) / sizeof ( *_papi_hwd ) ) - 1;
1882 
1883 /*
1884  * Routine that initializes all available components.
1885  * A component is available if a pointer to its info vector
1886  * appears in the NULL terminated_papi_hwd table.
1887  */
1888 int
1890 {
1891  int retval, i = 0;
1892 
1894  if ( retval != PAPI_OK ) {
1895  return retval;
1896  }
1897 
1898  while ( _papi_hwd[i] ) {
1899 
1900  retval = _papi_hwi_innoculate_vector( _papi_hwd[i] );
1901  if ( retval != PAPI_OK ) {
1902  return retval;
1903  }
1904 
1905  /* We can be disabled by user before init */
1906  if (!_papi_hwd[i]->cmp_info.disabled) {
1907  retval = _papi_hwd[i]->init_component( i );
1909 
1910  /* Do some sanity checking */
1911  if (retval==PAPI_OK) {
1912  if (_papi_hwd[i]->cmp_info.num_cntrs >
1914  fprintf(stderr,"Warning! num_cntrs is more than num_mpx_cntrs\n");
1915  }
1916 
1917  }
1918  }
1919 
1920  i++;
1921  }
1922  return PAPI_OK;
1923 }
1924 
1925 /* Machine info struct initialization using defaults */
1926 /* See _papi_mdi definition in papi_internal.h */
1927 
1928 int
1930 {
1931 
1932  int retval;
1933 
1934  memset(&_papi_hwi_system_info,0x0,sizeof( _papi_hwi_system_info ));
1935 
1937 
1938  /* Global struct to maintain EventSet mapping */
1939  retval = allocate_eventset_map( &_papi_hwi_system_info.global_eventset_map );
1940  if ( retval != PAPI_OK ) {
1941  return retval;
1942  }
1943 
1944  _papi_hwi_system_info.pid = 0; /* Process identifier */
1945 
1946  /* PAPI_hw_info_t struct */
1947  memset(&(_papi_hwi_system_info.hw_info),0x0,sizeof(PAPI_hw_info_t));
1948 
1949  return PAPI_OK;
1950 }
1951 
1952 void
1954 {
1956 
1958 
1960 
1961  papi_free( _papi_hwi_system_info.global_eventset_map.dataSlotArray );
1962  memset( &_papi_hwi_system_info.global_eventset_map,
1963  0x00, sizeof ( DynamicArray_t ) );
1964 
1966 
1967  if ( _papi_hwi_system_info.shlib_info.map ) {
1968  papi_free( _papi_hwi_system_info.shlib_info.map );
1969  }
1970  memset( &_papi_hwi_system_info, 0x0, sizeof ( _papi_hwi_system_info ) );
1971 
1972 }
1973 
1974 
1975 
1976 void
1977 _papi_hwi_dummy_handler( int EventSet, void *address, long long overflow_vector,
1978  void *context )
1979 {
1980  /* This function is not used and shouldn't be called. */
1981  ( void ) EventSet; /*unused */
1982  ( void ) address; /*unused */
1983  ( void ) overflow_vector; /*unused */
1984  ( void ) context; /*unused */
1985  return;
1986 }
1987 
1988 static long long
1989 handle_derived_add( int *position, long long *from )
1990 {
1991  int pos, i;
1992  long long retval = 0;
1993 
1994  i = 0;
1995  while ( i < PAPI_EVENTS_IN_DERIVED_EVENT ) {
1996  pos = position[i++];
1997  if ( pos == PAPI_NULL )
1998  break;
1999  INTDBG( "Compound event, adding %lld to %lld\n", from[pos], retval );
2000  retval += from[pos];
2001  }
2002  return ( retval );
2003 }
2004 
2005 static long long
2006 handle_derived_subtract( int *position, long long *from )
2007 {
2008  int pos, i;
2009  long long retval = from[position[0]];
2010 
2011  i = 1;
2012  while ( i < PAPI_EVENTS_IN_DERIVED_EVENT ) {
2013  pos = position[i++];
2014  if ( pos == PAPI_NULL )
2015  break;
2016  INTDBG( "Compound event, subtracting pos=%d %lld from %lld\n", pos,
2017  from[pos], retval );
2018  retval -= from[pos];
2019  }
2020  return ( retval );
2021 }
2022 
2023 static long long
2024 units_per_second( long long units, long long cycles )
2025 {
2026  return ( ( units * (long long) _papi_hwi_system_info.hw_info.cpu_max_mhz *
2027  (long long) 1000000 ) / cycles );
2028 }
2029 
2030 static long long
2031 handle_derived_ps( int *position, long long *from )
2032 {
2033  return ( units_per_second( from[position[1]], from[position[0]] ) );
2034 }
2035 static long long
2036 handle_derived_add_ps( int *position, long long *from )
2037 {
2038  long long tmp = handle_derived_add( position + 1, from );
2039  return ( units_per_second( tmp, from[position[0]] ) );
2040 }
2041 
2042 /* this function implement postfix calculation, it reads in a string where I use:
2043  | as delimiter
2044  N2 indicate No. 2 native event in the derived preset
2045  +, -, *, /, % as operator
2046  # as MHZ(million hz) got from _papi_hwi_system_info.hw_info.cpu_max_mhz*1000000.0
2047 
2048  Haihang (you@cs.utk.edu)
2049 */
2050 static long long
2051 _papi_hwi_postfix_calc( EventInfo_t * evi, long long *hw_counter )
2052 {
2053  char *point = evi->ops, operand[16];
2054  double stack[PAPI_EVENTS_IN_DERIVED_EVENT];
2055  int i, top = 0;
2056 
2057  memset(&stack,0,PAPI_EVENTS_IN_DERIVED_EVENT*sizeof(double));
2058 
2059  while ( *point != '\0' ) {
2060  if ( *point == 'N' ) { /* to get count for each native event */
2061  i = 0;
2062  point++;
2063  do {
2064  operand[i] = *point;
2065  point++;
2066  i++;
2067  } while ( *point != '|' );
2068  operand[i] = '\0';
2069  stack[top] = ( double ) hw_counter[evi->pos[atoi( operand )]];
2070  top++;
2071  point++;
2072  } else if ( *point == '#' ) { /* to get mhz, ignore the rest char's */
2073  stack[top] = _papi_hwi_system_info.hw_info.cpu_max_mhz * 1000000.0;
2074  top++;
2075  do {
2076  point++;
2077  } while ( *point != '|' );
2078  point++;
2079  } else if ( isdigit( *point ) ) { /* to get integer, I suppose only integer will be used,
2080  no error check here, please only use integer */
2081  i = 0;
2082  do {
2083  operand[i] = *point;
2084  point++;
2085  i++;
2086  } while ( *point != '|' );
2087  operand[i] = '\0';
2088  stack[top] = atoi( operand );
2089  top++;
2090  point++;
2091  } else if ( *point == '+' ) { /* + calculation */
2092  stack[top - 2] += stack[top - 1];
2093  top--;
2094  do {
2095  point++;
2096  } while ( *point != '|' );
2097  point++;
2098  } else if ( *point == '-' ) { /* - calculation */
2099  stack[top - 2] -= stack[top - 1];
2100  top--;
2101  do {
2102  point++;
2103  } while ( *point != '|' );
2104  point++;
2105  } else if ( *point == '*' ) { /* * calculation */
2106  stack[top - 2] *= stack[top - 1];
2107  top--;
2108  do {
2109  point++;
2110  } while ( *point != '|' );
2111  point++;
2112  } else if ( *point == '/' ) { /* / calculation */
2113  stack[top - 2] /= stack[top - 1];
2114  top--;
2115  do {
2116  point++;
2117  } while ( *point != '|' );
2118  point++;
2119  } else { /* do nothing */
2120  do {
2121  point++;
2122  } while ( *point != '|' );
2123  point++;
2124  }
2125  }
2126  return ( long long ) stack[0];
2127 }
2128 
2129 static long long
2130 handle_derived( EventInfo_t * evi, long long *from )
2131 {
2132  switch ( evi->derived ) {
2133  case DERIVED_ADD:
2134  return ( handle_derived_add( evi->pos, from ) );
2135  case DERIVED_ADD_PS:
2136  return ( handle_derived_add_ps( evi->pos, from ) );
2137  case DERIVED_SUB:
2138  return ( handle_derived_subtract( evi->pos, from ) );
2139  case DERIVED_PS:
2140  return ( handle_derived_ps( evi->pos, from ) );
2141  case DERIVED_POSTFIX:
2142  return ( _papi_hwi_postfix_calc( evi, from ) );
2143  case DERIVED_CMPD: /* This type has existed for a long time, but was never implemented.
2144  Probably because its a no-op. However, if it's in a header, it
2145  should be supported. As I found out when I implemented it in
2146  Pentium 4 for testing...dkt */
2147  return ( from[evi->pos[0]] );
2148  default:
2149  PAPIERROR( "BUG! Unknown derived command %d, returning 0",
2150  evi->derived );
2151  return ( ( long long ) 0 );
2152  }
2153 }
2154 
2155 
2156 /* table matching derived types to derived strings.
2157  used by get_info, encode_event, xml translator
2158 */
2160  {NOT_DERIVED, "NOT_DERIVED", "Do nothing"},
2161  {DERIVED_ADD, "DERIVED_ADD", "Add counters"},
2162  {DERIVED_PS, "DERIVED_PS",
2163  "Divide by the cycle counter and convert to seconds"},
2164  {DERIVED_ADD_PS, "DERIVED_ADD_PS",
2165  "Add 2 counters then divide by the cycle counter and xl8 to secs."},
2166  {DERIVED_CMPD, "DERIVED_CMPD",
2167  "Event lives in first counter but takes 2 or more codes"},
2168  {DERIVED_SUB, "DERIVED_SUB", "Sub all counters from first counter"},
2169  {DERIVED_POSTFIX, "DERIVED_POSTFIX",
2170  "Process counters based on specified postfix string"},
2171  {-1, NULL, NULL}
2172 };
2173 
2174 /* _papi_hwi_derived_type:
2175  Helper routine to extract a derived type from a derived string
2176  returns type value if found, otherwise returns -1
2177 */
2178 int
2179 _papi_hwi_derived_type( char *tmp, int *code )
2180 {
2181  int i = 0;
2182  while ( _papi_hwi_derived[i].name != NULL ) {
2183  if ( strcasecmp( tmp, _papi_hwi_derived[i].name ) == 0 ) {
2184  *code = _papi_hwi_derived[i].value;
2185  return PAPI_OK;
2186  }
2187  i++;
2188  }
2189  INTDBG( "Invalid derived string %s\n", tmp );
2190  return PAPI_EINVAL;
2191 }
2192 
2193 
2194 /* _papi_hwi_derived_string:
2195  Helper routine to extract a derived string from a derived type
2196  copies derived type string into derived if found,
2197  otherwise returns PAPI_EINVAL
2198 */
2199 static int
2200 _papi_hwi_derived_string( int type, char *derived, int len )
2201 {
2202  int j;
2203 
2204  for ( j = 0; _papi_hwi_derived[j].value != -1; j++ ) {
2205  if ( _papi_hwi_derived[j].value == type ) {
2206  strncpy( derived, _papi_hwi_derived[j].name, ( size_t )\
2207  len );
2208  return PAPI_OK;
2209  }
2210  }
2211  INTDBG( "Invalid derived type %d\n", type );
2212  return PAPI_EINVAL;
2213 }
2214 
2215 
2216 /* _papi_hwi_get_preset_event_info:
2217  Assumes EventCode contains a valid preset code.
2218  But defensive programming says check for NULL pointers.
2219  Returns a filled in PAPI_event_info_t structure containing
2220  descriptive strings and values for the specified preset event.
2221 */
2222 int
2224 {
2225  INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info);
2226 
2227  int i = EventCode & PAPI_PRESET_AND_MASK;
2228  unsigned int j;
2229 
2230  if ( _papi_hwi_presets[i].symbol ) { /* if the event is in the preset table */
2231  // since we are setting the whole structure to zero the strncpy calls below will
2232  // be leaving NULL terminates strings as long as they copy 1 less byte than the
2233  // buffer size of the field.
2234  memset( info, 0, sizeof ( PAPI_event_info_t ) );
2235 
2236  info->event_code = ( unsigned int ) EventCode;
2237  strncpy( info->symbol, _papi_hwi_presets[i].symbol,
2238  sizeof(info->symbol)-1);
2239 
2240  if ( _papi_hwi_presets[i].short_descr != NULL )
2241  strncpy( info->short_descr, _papi_hwi_presets[i].short_descr,
2242  sizeof ( info->short_descr )-1 );
2243 
2244  if ( _papi_hwi_presets[i].long_descr != NULL )
2245  strncpy( info->long_descr, _papi_hwi_presets[i].long_descr,
2246  sizeof ( info->long_descr )-1 );
2247 
2249  info->count = _papi_hwi_presets[i].count;
2250 
2252  info->derived, sizeof ( info->derived ) );
2253 
2254  if ( _papi_hwi_presets[i].postfix != NULL )
2255  strncpy( info->postfix, _papi_hwi_presets[i].postfix,
2256  sizeof ( info->postfix )-1 );
2257 
2258  for(j=0;j < info->count; j++) {
2259  info->code[j]=_papi_hwi_presets[i].code[j];
2260  strncpy(info->name[j], _papi_hwi_presets[i].name[j],
2261  sizeof(info->name[j])-1);
2262  }
2263 
2264  if ( _papi_hwi_presets[i].note != NULL ) {
2265  strncpy( info->note, _papi_hwi_presets[i].note,
2266  sizeof ( info->note )-1 );
2267  }
2268 
2269  return PAPI_OK;
2270  } else {
2271  return PAPI_ENOEVNT;
2272  }
2273 }
2274 
2275 
2276 /* Returns PAPI_OK if native EventCode found, or PAPI_ENOEVNT if not;
2277  Used to enumerate the entire array, e.g. for native_avail.c */
2278 int
2279 _papi_hwi_query_native_event( unsigned int EventCode )
2280 {
2281  INTDBG("ENTER: EventCode: %#x\n", EventCode);
2282  char name[PAPI_HUGE_STR_LEN]; /* probably overkill, */
2283  /* but should always be big enough */
2284  int cidx;
2285  int nevt_code;
2286 
2287  cidx = _papi_hwi_component_index( EventCode );
2288  if (cidx<0) {
2289  INTDBG("EXIT: PAPI_ENOCMP\n");
2290  return PAPI_ENOCMP;
2291  }
2292 
2293  // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
2294  _papi_hwi_set_papi_event_code(EventCode, 0);
2295 
2296  if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
2297  INTDBG("EXIT: nevt_code: %d\n", nevt_code);
2298  return nevt_code;
2299  }
2300  int ret = _papi_hwd[cidx]->ntv_code_to_name( (unsigned int)nevt_code, name, sizeof(name));
2301 
2302  INTDBG("EXIT: ret: %d\n", ret);
2303  return (ret);
2304 }
2305 
2306 /* Converts an ASCII name into a native event code usable by other routines
2307  Returns code = 0 and PAPI_OK if name not found.
2308  This allows for sparse native event arrays */
2309 int
2311 {
2312  INTDBG("ENTER: in: %s, out: %p\n", in, out);
2313 
2314  int retval = PAPI_ENOEVNT;
2315  char name[PAPI_HUGE_STR_LEN]; /* make sure it's big enough */
2316  unsigned int i;
2317  int cidx;
2318  char *full_event_name = strdup(in);
2319 
2321 
2322 
2323  for(cidx=0; cidx < papi_num_components; cidx++) {
2324 
2325  if (_papi_hwd[cidx]->cmp_info.disabled) continue;
2326 
2327  // if this component does not support the pmu which defines this event, no need to call it
2328  if (is_supported_by_component(cidx, full_event_name) == 0) continue;
2329 
2330  INTDBG("cidx: %d, name: %s, event: %s\n", cidx, _papi_hwd[cidx]->cmp_info.name, in);
2331 
2332  // show that we do not have an event code yet (the component may create one and update this info)
2333  // this also clears any values left over from a previous call
2335 
2336  /* first check the component for name_to_code */
2337  retval = _papi_hwd[cidx]->ntv_name_to_code( in, ( unsigned * ) out );
2338  if (retval==PAPI_OK) {
2339  *out = _papi_hwi_native_to_eventcode(cidx, *out, -1, in);
2340  free (full_event_name);
2341  INTDBG("EXIT: PAPI_OK event: %s code: %#x\n", in, *out);
2342  return PAPI_OK;
2343  }
2344 
2345  /* If not implemented, work around */
2346  if ( retval==PAPI_ECMP) {
2347  i = 0;
2349 
2350 // _papi_hwi_lock( INTERNAL_LOCK );
2351 
2352  do {
2353  // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
2355  retval = _papi_hwd[cidx]->ntv_code_to_name(
2356  i,
2357  name, sizeof(name));
2358  /* printf("%#x\nname =|%s|\ninput=|%s|\n", i, name, in); */
2359  if ( retval == PAPI_OK && in != NULL) {
2360  if ( strcasecmp( name, in ) == 0 ) {
2361  *out = _papi_hwi_native_to_eventcode(cidx, i, -1, name);
2362  INTDBG("EXIT: PAPI_OK, event: %s, code: %#x\n", in, *out);
2363  return PAPI_OK;
2364  }
2365  retval = PAPI_ENOEVNT;
2366  } else {
2367  *out = 0;
2368  retval = PAPI_ENOEVNT;
2369  break;
2370  }
2371  } while ( ( _papi_hwd[cidx]->ntv_enum_events( &i, PAPI_ENUM_EVENTS ) == PAPI_OK ) );
2372 
2373 // _papi_hwi_unlock( INTERNAL_LOCK );
2374  }
2375  }
2376 
2377  free (full_event_name);
2378  INTDBG("EXIT: retval: %d\n", retval);
2379  return retval;
2380 }
2381 
2382 /* Returns event name based on native event code.
2383  Returns NULL if name not found */
2384 int
2385 _papi_hwi_native_code_to_name( unsigned int EventCode,
2386  char *hwi_name, int len )
2387 {
2388  INTDBG("ENTER: EventCode: %#x, hwi_name: %p, len: %d\n", EventCode, hwi_name, len);
2389  int cidx;
2390  int retval;
2391  int nevt_code;
2392 
2393  cidx = _papi_hwi_component_index( EventCode );
2394  if (cidx<0) return PAPI_ENOEVNT;
2395 
2396  if ( EventCode & PAPI_NATIVE_MASK ) {
2397  // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
2398  _papi_hwi_set_papi_event_code(EventCode, 0);
2399 
2400  if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
2401  INTDBG("EXIT: nevt_code: %d\n", nevt_code);
2402  return nevt_code;
2403  }
2404  if ( (retval = _papi_hwd[cidx]->ntv_code_to_name(
2405  (unsigned int)nevt_code,
2406  hwi_name, len) ) == PAPI_OK ) {
2407  retval = _papi_hwi_prefix_component_name( _papi_hwd[cidx]->cmp_info.short_name,
2408  hwi_name, hwi_name, len);
2409  INTDBG("EXIT: retval: %d\n", retval);
2410  return retval;
2411  }
2412  INTDBG("EXIT: retval: %d\n", retval);
2413  return (retval);
2414  }
2415  INTDBG("EXIT: PAPI_ENOEVNT\n");
2416  return PAPI_ENOEVNT;
2417 }
2418 
2419 
2420 
2421 /* The native event equivalent of PAPI_get_event_info */
2422 int
2423 _papi_hwi_get_native_event_info( unsigned int EventCode,
2424  PAPI_event_info_t *info )
2425 {
2426  INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info);
2427  int retval;
2428  int cidx;
2429  int nevt_code;
2430 
2431  cidx = _papi_hwi_component_index( EventCode );
2432  if (cidx<0) return PAPI_ENOCMP;
2433 
2434  if (_papi_hwd[cidx]->cmp_info.disabled) return PAPI_ENOCMP;
2435 
2436  if ( EventCode & PAPI_NATIVE_MASK ) {
2437  // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
2438  _papi_hwi_set_papi_event_code(EventCode, 0);
2439 
2440  /* clear the event info */
2441  memset( info, 0, sizeof ( PAPI_event_info_t ) );
2442  info->event_code = ( unsigned int ) EventCode;
2443 
2444  retval = _papi_hwd[cidx]->ntv_code_to_info(
2445  _papi_hwi_eventcode_to_native(EventCode), info);
2446 
2447  /* If component error, it's missing the ntv_code_to_info vector */
2448  /* so we'll have to fake it. */
2449  if ( retval == PAPI_ECMP ) {
2450 
2451 
2452  INTDBG("missing NTV_CODE_TO_INFO, faking\n");
2453  /* Fill in the info structure */
2454 
2455  if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
2456  INTDBG("EXIT: nevt_code: %d\n", nevt_code);
2457  return nevt_code;
2458  }
2459  if ( (retval = _papi_hwd[cidx]->ntv_code_to_name(
2460  (unsigned int)nevt_code,
2461  info->symbol,
2462  sizeof(info->symbol)) ) == PAPI_OK ) {
2463 
2464  } else {
2465  INTDBG("EXIT: retval: %d\n", retval);
2466  return retval;
2467  }
2468 
2469  if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) <0) {
2470  INTDBG("EXIT: nevt_code: %d\n", nevt_code);
2471  return nevt_code;
2472  }
2473  retval = _papi_hwd[cidx]->ntv_code_to_descr(
2474  (unsigned int)nevt_code,
2475  info->long_descr,
2476  sizeof ( info->long_descr));
2477  if (retval!=PAPI_OK) {
2478  INTDBG("Failed ntv_code_to_descr()\n");
2479  }
2480 
2481  }
2483  _papi_hwd[cidx]->cmp_info.short_name,
2484  info->symbol,
2485  info->symbol,
2486  sizeof(info->symbol) );
2487 
2488  INTDBG("EXIT: retval: %d\n", retval);
2489  return retval;
2490  }
2491 
2492  INTDBG("EXIT: PAPI_ENOEVNT\n");
2493  return PAPI_ENOEVNT;
2494 }
2495 
2498 {
2499  const DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
2500  EventSetInfo_t *set;
2501 
2502  if ( ( eventset < 0 ) || ( eventset > map->totalSlots ) )
2503  return ( NULL );
2504 
2505  set = map->dataSlotArray[eventset];
2506 #ifdef DEBUG
2507  if ( ( ISLEVEL( DEBUG_THREADS ) ) && ( _papi_hwi_thread_id_fn ) &&
2508  ( set->master->tid != _papi_hwi_thread_id_fn( ) ) )
2509  return ( NULL );
2510 #endif
2511 
2512  return ( set );
2513 }
2514 
2515 int
2517 {
2518  /* Are we multiplexing at all */
2519  if ( ( ESI->state & PAPI_MULTIPLEXING ) == 0 ) {
2520  return 0;
2521  }
2522 
2523  /* Does the component support kernel multiplexing */
2524  if ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex ) {
2525  /* Have we forced software multiplexing */
2526  if ( ESI->multiplex.flags == PAPI_MULTIPLEX_FORCE_SW ) {
2527  return 1;
2528  }
2529  /* Nope, using hardware multiplexing */
2530  return 0;
2531  }
2532 
2533  /* We are multiplexing but the component does not support hardware */
2534 
2535  return 1;
2536 
2537 }
2538 
2539 hwd_context_t *
2540 _papi_hwi_get_context( EventSetInfo_t * ESI, int *is_dirty )
2541 {
2542  INTDBG("Entry: ESI: %p, is_dirty: %p\n", ESI, is_dirty);
2543  int dirty_ctx;
2544  hwd_context_t *ctx=NULL;
2545 
2546  /* assume for now the control state is clean (last updated by this ESI) */
2547  dirty_ctx = 0;
2548 
2549  /* get a context pointer based on if we are counting for a thread or for a cpu */
2550  if (ESI->state & PAPI_CPU_ATTACHED) {
2551  /* use cpu context */
2552  ctx = ESI->CpuInfo->context[ESI->CmpIdx];
2553 
2554  /* if the user wants to know if the control state was last set by the same event set, tell him */
2555  if (is_dirty != NULL) {
2556  if (ESI->CpuInfo->from_esi != ESI) {
2557  dirty_ctx = 1;
2558  }
2559  *is_dirty = dirty_ctx;
2560  }
2561  ESI->CpuInfo->from_esi = ESI;
2562 
2563  } else {
2564 
2565  /* use thread context */
2566  ctx = ESI->master->context[ESI->CmpIdx];
2567 
2568  /* if the user wants to know if the control state was last set by the same event set, tell him */
2569  if (is_dirty != NULL) {
2570  if (ESI->master->from_esi != ESI) {
2571  dirty_ctx = 1;
2572  }
2573  *is_dirty = dirty_ctx;
2574  }
2575  ESI->master->from_esi = ESI;
2576 
2577  }
2578  return( ctx );
2579 }
char event_name[2][PAPI_MAX_STR_LEN]
Definition: data_range.c:23
int _papi_hwi_is_sw_multiplex(EventSetInfo_t *ESI)
#define PAPI_ENOEVNT
Definition: papi.h:258
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int atoi()
unsigned int count
Definition: papi.h:984
memset(eventId, 0, size)
int _papi_hwi_convert_eventset_to_multiplex(_papi_int_multiplex_t *mpx)
#define PAPI_NATIVE_MASK
#define DERIVED_SUB
Definition: papi_internal.h:74
int _papi_hwi_get_ntv_idx(unsigned int papi_evt_code)
int errno
int _papi_hwi_using_signal[PAPI_NSIG]
Definition: extras.c:363
static unsigned int papi_event_code
int _papi_hwi_init_global_internal(void)
#define PAPI_OVERFLOWING
Definition: papi.h:376
#define IS_PRESET(EventCode)
Definition: papi.h:227
unsigned int _papi_hwi_get_papi_event_code()
char * _papi_hwi_get_papi_event_string()
static struct native_event_info * _papi_native_events
Definition: papi_internal.c:76
#define PAPI_CPU_ATTACH
Definition: papi.h:455
char * getenv()
#define PAPI_VERB_ECONT
Definition: papi.h:387
#define PAPI_EVENTS_IN_DERIVED_EVENT
Definition: genpapifdef.c:39
int _papi_hwi_innoculate_os_vector(papi_os_vector_t *v)
Definition: papi_vector.c:200
Hardware info structure.
Definition: papi.h:777
hwd_register_t * ni_bits
static int EventInfoArrayLength(const EventSetInfo_t *ESI)
static int is_supported_by_component(int cidx, char *event_name)
long long flags
Definition: iozone.c:12330
#define IS_USER_DEFINED(EventCode)
Definition: papi.h:228
char * papi_event_string
Definition: papi_internal.c:87
int(* ntv_code_to_name)(unsigned int, char *, int)
Definition: papi_vector.h:45
#define papi_free(a)
Definition: papi_memory.h:35
int(* read)(hwd_context_t *, hwd_control_state_t *, long long **, int)
Definition: papi_vector.h:30
int _papi_hwi_query_native_event(unsigned int EventCode)
int _papi_hwi_cleanup_eventset(EventSetInfo_t *ESI)
start
Definition: iozone.c:22736
#define papi_malloc(a)
Definition: papi_memory.h:34
int default_granularity
Definition: papi.h:642
PAPI_debug_handler_t _papi_hwi_debug_handler
Definition: papi_internal.c:56
#define PAPI_NULL
Definition: papi.h:290
MPX_EventSet * mpx_evset
Definition: sw_multiplex.h:32
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:966
int(* init_control_state)(hwd_control_state_t *ptr)
Definition: papi_vector.h:37
int EventSet
Definition: data_range.c:25
#define PAPI_MAX_PRESET_EVENTS
int _papi_hwi_native_code_to_name(unsigned int EventCode, char *hwi_name, int len)
void _papi_hwi_dummy_handler(int EventSet, void *address, long long overflow_vector, void *context)
EventSetAttachInfo_t attach
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:963
device[deviceId] domain[domainId] event
Definition: linux-cuda.c:306
#define PAPI_MULTIPLEXING
Definition: papi.h:378
#define PAPI_MULTIPLEX_FORCE_SW
Definition: papi.h:417
static int _papi_hwi_find_native_event(int cidx, int event, const char *event_name)
hwd_register_t * NativeBits
void _papi_hwi_free_papi_event_string()
int events[PAPI_EVENTS_IN_DERIVED_EVENT]
static long long handle_derived_subtract(int *position, long long *from)
static int _papi_hwi_derived_string(int type, char *derived, int len)
EventSetDomainInfo_t domain
#define PAPI_EBUG
Definition: papi.h:257
int _papi_hwi_errno
Definition: papi_internal.c:58
int _papi_hwi_remove_EventSet(EventSetInfo_t *ESI)
int _papi_hwi_derived_type(char *tmp, int *code)
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
va_start(arg_list, fmt)
static long long _papi_hwi_postfix_calc(EventInfo_t *evi, long long *hw_counter)
#define DERIVED_ADD
Definition: papi_internal.h:70
#define PAPI_PRESET_MASK
void
Definition: iozone.c:18627
char note[PAPI_HUGE_STR_LEN]
Definition: papi.h:1010
return PAPI_EINVAL
Definition: linux-nvml.c:408
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
void _papi_hwi_init_errors(void)
#define PAPI_NOT_INITED
Definition: papi.h:278
int _papi_hwi_remove_event(EventSetInfo_t *ESI, int EventCode)
EventSetInfo_t * _papi_hwi_lookup_EventSet(int eventset)
#define DERIVED_CMPD
Definition: papi_internal.h:73
void double value
Definition: iozone.c:18781
static double
Definition: fileop.c:1281
int _papi_hwi_native_name_to_code(char *in, int *out)
papi_vector_t * _papi_hwd[]
#define PAPI_INIT_SLOTS
Definition: papi.h:459
#define PAPI_HUGE_STR_LEN
Definition: papi.h:465
PAPI_shlib_info_t shlib_info
Return codes and api definitions.
#define PAPI_CPU_ATTACHED
Definition: papi.h:380
#define INTDBG(format, args...)
Definition: papi_debug.h:65
static long long handle_derived_add(int *position, long long *from)
char events[MAX_EVENTS][BUFSIZ]
int MPX_add_events(MPX_EventSet **mpx_events, int *event_list, int num_events, int domain, int granularity)
Definition: sw_multiplex.c:676
long long ret
Definition: iozone.c:1346
#define PAPI_EMISC
Definition: papi.h:265
unsigned int event_type
Definition: papi_preset.h:30
char * _papi_hwi_strip_component_prefix(char *event_name)
static int _papi_hwi_add_error(char *error)
static void _papi_hwi_cleanup_errors()
papi_os_vector_t _papi_os_vector
Definition: aix.c:1288
int i
Definition: fileop.c:140
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
int _papi_hwi_native_to_eventcode(int cidx, int event_code, int ntv_idx, const char *event_name)
EventSetOverflowInfo_t overflow
#define PAPI_PMU_MAX
Definition: papi.h:467
static int event_already_in_eventset(EventSetInfo_t *ESI, int papi_event)
#define PAPI_OVERFLOW_HARDWARE
Definition: papi.h:410
EventSetInheritInfo_t inherit
struct _CpuInfo * CpuInfo
DynamicArray_t global_eventset_map
struct _ThreadInfo * master
#define IS_NATIVE(EventCode)
Definition: papi.h:226
static int allocate_eventset_map(DynamicArray_t *map)
#define NOT_DERIVED
Definition: papi_internal.h:69
char *long long size
Definition: iozone.c:12023
free(dummyfile[xx])
int k
Definition: iozone.c:19136
static int cidx
Definition: event_info.c:40
int _papi_hwi_read(hwd_context_t *context, EventSetInfo_t *ESI, long long *values)
PAPI_sprofil_t ** prof
char short_descr[PAPI_MIN_STR_LEN]
Definition: papi.h:964
hwi_presets_t _papi_hwi_presets[PAPI_MAX_PRESET_EVENTS]
#define PAPI_ESYS
Definition: papi.h:253
static int native
Definition: event_info.c:39
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
int _papi_hwi_innoculate_vector(papi_vector_t *v)
Definition: papi_vector.c:109
int(* allocate_registers)(EventSetInfo_t *)
Definition: papi_vector.h:49
int _papi_hwi_lookup_EventCodeIndex(const EventSetInfo_t *ESI, unsigned int EventCode)
static int update_overflow(EventSetInfo_t *ESI)
#define NATIVE_EVENT_CHUNKSIZE
Definition: papi_internal.c:65
int _papi_hwi_add_event(EventSetInfo_t *ESI, int EventCode)
long long
Definition: iozone.c:19827
#define PAPI_ECNFLCT
Definition: papi.h:259
int _papi_hwi_get_native_event_info(unsigned int EventCode, PAPI_event_info_t *info)
unsigned int event_type
Definition: papi.h:989
void PAPIERROR(char *format,...)
static const hwi_describe_t _papi_hwi_derived[]
int(* PAPI_debug_handler_t)(int code)
Definition: papi.h:682
int(* ntv_code_to_info)(unsigned int, PAPI_event_info_t *)
Definition: papi_vector.h:48
void _papi_hwi_shutdown_global_internal(void)
int _papi_hwi_get_preset_event_info(int EventCode, PAPI_event_info_t *info)
int mpx_add_event(MPX_EventSet **mpx_events, int EventCode, int domain, int granularity)
Definition: sw_multiplex.c:305
static int num_native_chunks
Definition: papi_internal.c:78
unsigned int kernel_multiplex
Definition: papi.h:653
#define PAPI_ECMP
Definition: papi.h:254
#define DERIVED_PS
Definition: papi_internal.h:71
static long long units_per_second(long long units, long long cycles)
int _papi_hwi_error_level
Definition: papi_internal.c:55
nvmlDevice_t handle
Definition: linux-nvml.c:399
static int default_debug_handler(int errorCode)
static int num_error_chunks
Definition: papi_internal.c:81
int _papi_hwi_shutdown_cpu(CpuInfo_t *cpu)
Definition: cpus.c:306
NativeInfo_t * NativeInfoArray
int _papi_hwi_num_errors
Definition: papi_internal.c:59
char * short_descr
Definition: papi_preset.h:25
EventInfo_t * EventInfoArray
#define PAPI_ENOMEM
Definition: papi.h:252
static int remove_native_events(EventSetInfo_t *ESI, int *nevt, int size)
unsigned long int(* _papi_hwi_thread_id_fn)(void)
Definition: threads.c:42
long long * hw_start
unsigned int code[PAPI_MAX_INFO_TERMS]
Definition: papi.h:1000
#define PAPI_ERROR_CODE_str
Definition: papi_internal.h:41
static long long handle_derived_ps(int *position, long long *from)
int(* set_domain)(hwd_control_state_t *, int)
Definition: papi_vector.h:42
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_ENOCMP
Definition: papi.h:268
cmp_struct_sizes_t size
Definition: papi_vector.h:23
EventSetMultiplexInfo_t multiplex
goto out
Definition: pscanf.h:20
EventSetGranularityInfo_t granularity
hwd_context_t * _papi_hwi_get_context(EventSetInfo_t *ESI, int *is_dirty)
EventSetInfo_t ** dataSlotArray
int pos[PAPI_EVENTS_IN_DERIVED_EVENT]
va_end(arg_list)
long long * sw_stop
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
int _papi_hwi_publish_error(char *error)
int papi_num_components
#define INTERNAL_LOCK
Definition: papi_internal.h:85
#define papi_realloc(a, b)
Definition: papi_memory.h:36
char operation[USER_EVENT_OPERATION_LEN]
int(* ntv_enum_events)(unsigned int *, int)
Definition: papi_vector.h:43
char * name
Definition: iozone.c:23648
int _papi_hwi_assign_eventset(EventSetInfo_t *ESI, int cidx)
static int add_native_fail_clean(EventSetInfo_t *ESI, int nevt)
char * long_descr
Definition: papi_preset.h:26
int _papi_hwi_init_global(void)
PAPI_address_map_t * map
Definition: papi.h:711
char ** _papi_errlist
Definition: papi_internal.c:80
int mpx_remove_event(MPX_EventSet **mpx_events, int EventCode)
Definition: sw_multiplex.c:418
int cpu_max_mhz
Definition: papi.h:793
static int _papi_hwi_lookup_error(char *error)
int
Definition: iozone.c:18528
int(* update_control_state)(hwd_control_state_t *, NativeInfo_t *, int, hwd_context_t *)
Definition: papi_vector.h:38
int temp
Definition: iozone.c:22158
unsigned int code[PAPI_MAX_INFO_TERMS]
Definition: papi_preset.h:32
#define ISLEVEL(a)
Definition: papi_debug.h:54
char * name[PAPI_MAX_INFO_TERMS]
Definition: papi_preset.h:33
int(* ntv_name_to_code)(char *, unsigned int *)
Definition: papi_vector.h:44
int _papi_hwi_component_index(int event_code)
#define PAPI_NATIVE_AND_MASK
#define PAPI_QUIET
Definition: papi.h:386
unsigned int event_code
#define PAPI_STOPPED
Definition: papi.h:372
#define PAPI_UE_AND_MASK
#define PAPI_PRESET_AND_MASK
int(* ntv_code_to_descr)(unsigned int, char *, int)
Definition: papi_vector.h:46
static int _papi_hwi_add_native_event(int cidx, int ntv_event, int ntv_idx, const char *event_name)
int _papi_hwi_invalid_cmp(int cidx)
user_defined_event_t * _papi_user_events
#define DEBUG_THREADS
Definition: papi_debug.h:30
void _papi_hwi_free_EventSet(EventSetInfo_t *ESI)
static long long handle_derived(EventInfo_t *evi, long long *from)
int _papi_hwi_prefix_component_name(char *component_name, char *event_name, char *out, int out_len)
int _papi_hwi_eventcode_to_native(int event_code)
EventSetInfo_t * ESI
#define PAPI_VERB_ESTOP
Definition: papi.h:388
EventSetProfileInfo_t profile
static int add_native_events(EventSetInfo_t *ESI, unsigned int *nevt, int size, EventInfo_t *out)
return
Definition: iozone.c:22170
int init_level
Definition: papi_internal.c:54
hwd_control_state_t * ctl_state
#define DERIVED_ADD_PS
Definition: papi_internal.h:72
long j
Definition: iozone.c:19135
unsigned int event_code
Definition: papi.h:961
char * symbol
Definition: papi_preset.h:24
char derived[PAPI_MIN_STR_LEN]
Definition: papi.h:992
static long long values[NUM_EVENTS]
Definition: init_fini.c:10
ssize_t retval
Definition: libasync.c:338
long long tmp
Definition: iozone.c:12031
static long long handle_derived_add_ps(int *position, long long *from)
#define PAPI_ECOUNT
Definition: papi.h:274
char postfix[PAPI_2MAX_STR_LEN]
Definition: papi.h:995
size1
Definition: iozone.c:12039
int _papi_hwi_cleanup_all_presets(void)
Definition: papi_preset.c:107
unsigned int _papi_user_events_count
#define DERIVED_POSTFIX
Definition: papi_internal.h:75
unsigned int count
Definition: papi_preset.h:29
static int create_EventSet(EventSetInfo_t **here)
static int add_EventSet(EventSetInfo_t *ESI, ThreadInfo_t *master)
int(* init_component)(int)
Definition: papi_vector.h:35
static int get_free_EventCodeIndex(const EventSetInfo_t *ESI, unsigned int EventCode)
void _papi_hwi_map_events_to_native(EventSetInfo_t *ESI)
char name[PAPI_MAX_INFO_TERMS][PAPI_2MAX_STR_LEN]
Definition: papi.h:1006
int(* set_overflow)(EventSetInfo_t *, int, int)
Definition: papi_vector.h:40
static int expand_dynamic_array(DynamicArray_t *DA)
int _papi_hwi_create_eventset(int *EventSet, ThreadInfo_t *handle)
#define papi_calloc(a, b)
Definition: papi_memory.h:37
void _papi_hwi_set_papi_event_string(const char *event_string)
Definition: papi_internal.c:89
static int papi_event_code_changed
int n
Definition: mendes-alt.c:164
char * postfix
Definition: papi_preset.h:31
int sz
Definition: fileop.c:80
EventSetCpuInfo_t cpu
static int num_native_events
Definition: papi_internal.c:77
char * ptr
Definition: iozone.c:23586