PAPI  5.4.1.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 /* Advanced definitons */
48 static int default_debug_handler( int errorCode );
49 static long long handle_derived( EventInfo_t * evi, long long *from );
50 
51 /* 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
313 _papi_hwi_find_native_event(int cidx, int event, const char *event_name) {
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 (IS_PRESET(event_code)) {
522  INTDBG("EXIT: Event %#x is a PRESET, assigning component %d\n", event_code,0);
523  return 0;
524  }
525 
526  /* user defined events are treated like preset events (component 0 only) */
527  if (IS_USER_DEFINED(event_code)) {
528  INTDBG("EXIT: Event %#x is USER DEFINED, assigning component %d\n", event_code,0);
529  return 0;
530  }
531 
532  event_index=event_code&PAPI_NATIVE_AND_MASK;
533 
534  if ( (event_index < 0) || (event_index>=num_native_events)) {
535  INTDBG("EXIT: Event index %#x is out of range, num_native_events: %d\n", event_index, num_native_events);
536  return PAPI_ENOEVNT;
537  }
538 
539  cidx=_papi_native_events[event_index].cidx;
540 
541  if ((cidx<0) || (cidx >= papi_num_components)) {
542  INTDBG("EXIT: Component index %#x is out of range, papi_num_components: %d\n", cidx, papi_num_components);
543  return PAPI_ENOCMP;
544  }
545 
546  INTDBG("EXIT: Found cidx: %d event_index: %d, event_code: %#x\n", cidx, event_index, event_code);
547  return cidx;
548 }
549 
550 /* Convert an internal component event to a papi event code */
551 int
552 _papi_hwi_native_to_eventcode(int cidx, int event_code, int ntv_idx, const char *event_name) {
553  INTDBG("Entry: cidx: %d, event: %#x, ntv_idx: %d, event_name: %s\n", cidx, event_code, ntv_idx, event_name);
554 
555  int result;
556 
557  if (papi_event_code_changed > 0) {
559  INTDBG("EXIT: papi_event_code: %#x set by the component\n", result);
560  return result;
561  }
562 
563  result=_papi_hwi_find_native_event(cidx, event_code, event_name);
564  if (result==PAPI_ENOEVNT) {
565  // Need to create one
566  result=_papi_hwi_add_native_event(cidx, event_code, ntv_idx, event_name);
567  }
568 
569  INTDBG("EXIT: result: %#x\n", result);
570  return result;
571 }
572 
573 /* Convert a native_event code to an internal event code */
574 int
576  INTDBG("ENTER: event_code: %#x\n", event_code);
577 
578  int result;
579  int event_index;
580 
581  event_index=event_code&PAPI_NATIVE_AND_MASK;
582  if ((event_index < 0) || (event_index>=num_native_events)) {
583  INTDBG("EXIT: PAPI_ENOEVNT\n");
584  return PAPI_ENOEVNT;
585  }
586 
587  result=_papi_native_events[event_index].component_event;
588 
589  INTDBG("EXIT: result: %#x\n", result);
590  return result;
591 
592 }
593 
594 
595 /*********************/
596 /* Utility functions */
597 /*********************/
598 
599 void
600 PAPIERROR( char *format, ... )
601 {
602  va_list args;
603  if ( ( _papi_hwi_error_level != PAPI_QUIET ) ||
604  ( getenv( "PAPI_VERBOSE" ) ) ) {
605  va_start( args, format );
606  fprintf( stderr, "\nPAPI Error: " );
607  vfprintf( stderr, format, args );
608  fprintf( stderr, ".\n" );
609  va_end( args );
610  }
611 }
612 
613 static int
614 default_debug_handler( int errorCode )
615 {
616  char str[PAPI_HUGE_STR_LEN];
617 
618  if ( errorCode == PAPI_OK )
619  return ( errorCode );
620  if ( ( errorCode > 0 ) || ( -errorCode > _papi_hwi_num_errors ) ) {
621  PAPIERROR( "%s %d,%s,Bug! Unknown error code", PAPI_ERROR_CODE_str,
622  errorCode, "" );
623  return ( PAPI_EBUG );
624  }
625 
626  switch ( _papi_hwi_error_level ) {
627  case PAPI_VERB_ECONT:
628  case PAPI_VERB_ESTOP:
629  /* gcc 2.96 bug fix, do not change */
630  /* fprintf(stderr,"%s %d: %s: %s\n",PAPI_ERROR_CODE_str,errorCode,_papi_hwi_err[-errorCode].name,_papi_hwi_err[-errorCode].descr); */
631 
632  sprintf( str, "%s %d,%s", PAPI_ERROR_CODE_str, errorCode,
633  _papi_errlist[-errorCode] );
634  if ( errorCode == PAPI_ESYS )
635  sprintf( str + strlen( str ), ": %s", strerror( errno ) );
636 
637  PAPIERROR( str );
638 
640  abort( ); /* patch provided by will cohen of redhat */
641  else
642  return errorCode;
643  break;
644 
645  case PAPI_QUIET:
646  default:
647  return errorCode;
648  }
649  return ( PAPI_EBUG ); /* Never get here */
650 }
651 
652 static int
654 {
655  /* Allocate and clear the Dynamic Array structure */
656  if ( map->dataSlotArray != NULL )
657  papi_free( map->dataSlotArray );
658  memset( map, 0x00, sizeof ( DynamicArray_t ) );
659 
660  /* Allocate space for the EventSetInfo_t pointers */
661 
662  map->dataSlotArray =
664  sizeof ( EventSetInfo_t * ) );
665  if ( map->dataSlotArray == NULL ) {
666  return ( PAPI_ENOMEM );
667  }
668  memset( map->dataSlotArray, 0x00,
672  map->fullSlots = 0;
673 
674  return ( PAPI_OK );
675 }
676 
677 static int
679 {
680  int number;
681  EventSetInfo_t **n;
682 
683  /*realloc existing PAPI_EVENTSET_MAP.dataSlotArray */
684 
685  number = DA->totalSlots * 2;
686  n = ( EventSetInfo_t ** ) papi_realloc( DA->dataSlotArray,
687  ( size_t ) number *
688  sizeof ( EventSetInfo_t * ) );
689  if ( n == NULL )
690  return ( PAPI_ENOMEM );
691 
692  /* Need to assign this value, what if realloc moved it? */
693 
694  DA->dataSlotArray = n;
695 
696  memset( DA->dataSlotArray + DA->totalSlots, 0x00,
697  ( size_t ) DA->totalSlots * sizeof ( EventSetInfo_t * ) );
698 
699  DA->totalSlots = number;
700  DA->availSlots = number - DA->fullSlots;
701 
702  return ( PAPI_OK );
703 }
704 
705 static int
707 {
708  return ( _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs );
709 }
710 
711 
712 
713 
714 
715 /*========================================================================*/
716 /* This function allocates space for one EventSetInfo_t structure and for */
717 /* all of the pointers in this structure. If any malloc in this function */
718 /* fails, all memory malloced to the point of failure is freed, and NULL */
719 /* is returned. Upon success, a pointer to the EventSetInfo_t data */
720 /* structure is returned. */
721 /*========================================================================*/
722 
723 
724 static int
726 {
727  EventSetInfo_t *ESI;
728 
729  ESI = ( EventSetInfo_t * ) papi_calloc( 1, sizeof ( EventSetInfo_t ) );
730  if ( ESI == NULL ) {
731  return PAPI_ENOMEM;
732  }
733 
734  *here = ESI;
735 
736  return PAPI_OK;
737 }
738 
739 int
741 {
742  INTDBG("ENTER: ESI: %p (%d), cidx: %d\n", ESI, ESI->EventSetIndex, cidx);
743  int retval;
744  size_t max_counters;
745  char *ptr;
746  unsigned int i, j;
747 
748  /* If component doesn't exist... */
749  if (_papi_hwi_invalid_cmp(cidx)) return PAPI_ECMP;
750 
751  /* Assigned at create time */
753  ESI->granularity.granularity =
755  ESI->CmpIdx = cidx;
756 
757  /* ??? */
758  max_counters = ( size_t ) _papi_hwd[cidx]->cmp_info.num_mpx_cntrs;
759 
760  ESI->ctl_state = (hwd_control_state_t *) papi_calloc( 1, (size_t)
761  _papi_hwd[cidx]->size.control_state );
762  ESI->sw_stop = (long long *) papi_calloc( ( size_t ) max_counters,
763  sizeof ( long long ) );
764  ESI->hw_start = ( long long * ) papi_calloc( ( size_t ) max_counters,
765  sizeof ( long long ) );
766  ESI->EventInfoArray = ( EventInfo_t * ) papi_calloc( (size_t) max_counters,
767  sizeof ( EventInfo_t ) );
768 
769  /* allocate room for the native events and for the component-private */
770  /* register structures */
771  /* ugh is there a cleaner way to allocate this? vmw */
772  ESI->NativeInfoArray = ( NativeInfo_t * )
773  papi_calloc( ( size_t ) max_counters, sizeof ( NativeInfo_t ));
774 
775  ESI->NativeBits = papi_calloc(( size_t ) max_counters,
776  ( size_t ) _papi_hwd[cidx]->size.reg_value );
777 
778  /* NOTE: the next two malloc allocate blocks of memory that are later */
779  /* parcelled into overflow and profile arrays */
780  ESI->overflow.deadline = ( long long * )
781  papi_malloc( ( sizeof ( long long ) +
782  sizeof ( int ) * 3 ) * ( size_t ) max_counters );
783 
784  ESI->profile.prof = ( PAPI_sprofil_t ** )
785  papi_malloc( ( sizeof ( PAPI_sprofil_t * ) * ( size_t ) max_counters +
786  ( size_t ) max_counters * sizeof ( int ) * 4 ) );
787 
788  /* If any of these allocations failed, free things up and fail */
789 
790  if ( ( ESI->ctl_state == NULL ) ||
791  ( ESI->sw_stop == NULL ) ||
792  ( ESI->hw_start == NULL ) ||
793  ( ESI->NativeInfoArray == NULL ) ||
794  ( ESI->NativeBits == NULL ) ||
795  ( ESI->EventInfoArray == NULL ) ||
796  ( ESI->profile.prof == NULL ) ||
797  ( ESI->overflow.deadline == NULL ) ) {
798 
799  if ( ESI->sw_stop ) papi_free( ESI->sw_stop );
800  if ( ESI->hw_start ) papi_free( ESI->hw_start );
801  if ( ESI->EventInfoArray ) papi_free( ESI->EventInfoArray );
802  if ( ESI->NativeInfoArray ) papi_free( ESI->NativeInfoArray );
803  if ( ESI->NativeBits ) papi_free( ESI->NativeBits );
804  if ( ESI->ctl_state ) papi_free( ESI->ctl_state );
805  if ( ESI->overflow.deadline ) papi_free( ESI->overflow.deadline );
806  if ( ESI->profile.prof ) papi_free( ESI->profile.prof );
807  papi_free( ESI );
808  return PAPI_ENOMEM;
809  }
810 
811 
812  /* Carve up the overflow block into separate arrays */
813  ptr = ( char * ) ESI->overflow.deadline;
814  ptr += sizeof ( long long ) * max_counters;
815  ESI->overflow.threshold = ( int * ) ptr;
816  ptr += sizeof ( int ) * max_counters;
817  ESI->overflow.EventIndex = ( int * ) ptr;
818  ptr += sizeof ( int ) * max_counters;
819  ESI->overflow.EventCode = ( int * ) ptr;
820 
821  /* Carve up the profile block into separate arrays */
822  ptr = ( char * ) ESI->profile.prof +
823  ( sizeof ( PAPI_sprofil_t * ) * max_counters );
824  ESI->profile.count = ( int * ) ptr;
825  ptr += sizeof ( int ) * max_counters;
826  ESI->profile.threshold = ( int * ) ptr;
827  ptr += sizeof ( int ) * max_counters;
828  ESI->profile.EventIndex = ( int * ) ptr;
829  ptr += sizeof ( int ) * max_counters;
830  ESI->profile.EventCode = ( int * ) ptr;
831 
832  /* initialize_EventInfoArray */
833 
834  for ( i = 0; i < max_counters; i++ ) {
835  ESI->EventInfoArray[i].event_code=( unsigned int ) PAPI_NULL;
836  ESI->EventInfoArray[i].ops = NULL;
838  for ( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ ) {
839  ESI->EventInfoArray[i].pos[j] = PAPI_NULL;
840  }
841  }
842 
843  /* initialize_NativeInfoArray */
844  for( i = 0; i < max_counters; i++ ) {
845  ESI->NativeInfoArray[i].ni_event = -1;
846  ESI->NativeInfoArray[i].ni_position = -1;
847  ESI->NativeInfoArray[i].ni_papi_code = -1;
848  ESI->NativeInfoArray[i].ni_owners = 0;
849  ESI->NativeInfoArray[i].ni_bits = ((unsigned char*)ESI->NativeBits) +
851  }
852 
853  ESI->NativeCount = 0;
854 
855  ESI->state = PAPI_STOPPED;
856 
857  /* these used to be init_config */
858  retval = _papi_hwd[cidx]->init_control_state( ESI->ctl_state );
859  retval |= _papi_hwd[cidx]->set_domain( ESI->ctl_state, ESI->domain.domain);
860 
861  return retval;
862 }
863 
864 /*========================================================================*/
865 /* This function should free memory for one EventSetInfo_t structure. */
866 /* The argument list consists of a pointer to the EventSetInfo_t */
867 /* structure, *ESI. */
868 /* The calling function should check for ESI==NULL. */
869 /*========================================================================*/
870 
871 void
873 {
875 
876 #ifdef DEBUG
877  memset( ESI, 0x00, sizeof ( EventSetInfo_t ) );
878 #endif
879  papi_free( ESI );
880 
881 }
882 
883 static int
885 {
886  DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
887  int i, errorCode;
888 
890 
891  if ( map->availSlots == 0 ) {
892  errorCode = expand_dynamic_array( map );
893  if ( errorCode < PAPI_OK ) {
895  return ( errorCode );
896  }
897  }
898 
899  i = 0;
900  for ( i = 0; i < map->totalSlots; i++ ) {
901  if ( map->dataSlotArray[i] == NULL ) {
902  ESI->master = master;
903  ESI->EventSetIndex = i;
904  map->fullSlots++;
905  map->availSlots--;
906  map->dataSlotArray[i] = ESI;
908  return ( PAPI_OK );
909  }
910  }
911 
913  return ( PAPI_EBUG );
914 }
915 
916 int
918 {
919  EventSetInfo_t *ESI;
920  int retval;
921 
922  /* Is the EventSet already in existence? */
923 
924  if ( ( EventSet == NULL ) || ( handle == NULL ) )
925  return PAPI_EINVAL;
926 
927  if ( *EventSet != PAPI_NULL )
928  return PAPI_EINVAL;
929 
930  /* Well, then allocate a new one. Use n to keep track of a NEW EventSet */
931 
932  retval = create_EventSet( &ESI );
933  if ( retval != PAPI_OK )
934  return retval;
935 
936  ESI->CmpIdx = -1; /* when eventset is created, it is not decided yet which component it belongs to, until first event is added */
937  ESI->state = PAPI_STOPPED;
938 
939  /* Add it to the global table */
940 
941  retval = add_EventSet( ESI, handle );
942  if ( retval < PAPI_OK ) {
944  return retval ;
945  }
946 
947  *EventSet = ESI->EventSetIndex;
948 
949  INTDBG( "(%p,%p): new EventSet in slot %d\n",
950  ( void * ) EventSet, handle, *EventSet );
951 
952  return retval;
953 }
954 
955 /* This function returns the index of the the next free slot
956  in the EventInfoArray. If EventCode is already in the list,
957  it returns PAPI_ECNFLCT. */
958 
959 static int
960 get_free_EventCodeIndex( const EventSetInfo_t * ESI, unsigned int EventCode )
961 {
962  int k;
963  int lowslot = PAPI_ECNFLCT;
964  int limit = EventInfoArrayLength( ESI );
965 
966  /* Check for duplicate events and get the lowest empty slot */
967 
968  for ( k = 0; k < limit; k++ ) {
969  if ( ESI->EventInfoArray[k].event_code == EventCode )
970  return ( PAPI_ECNFLCT );
971  /*if ((ESI->EventInfoArray[k].event_code == PAPI_NULL) && (lowslot == PAPI_ECNFLCT)) */
972  if ( ESI->EventInfoArray[k].event_code == ( unsigned int ) PAPI_NULL ) {
973  lowslot = k;
974  break;
975  }
976  }
977  return ( lowslot );
978 }
979 
980 /* This function returns the index of the EventCode or error */
981 /* Index to what? The index to everything stored EventCode in the */
982 /* EventSet. */
983 
984 int
986  unsigned int EventCode )
987 {
988  int i;
989  int limit = EventInfoArrayLength( ESI );
990 
991  for ( i = 0; i < limit; i++ ) {
992  if ( ESI->EventInfoArray[i].event_code == EventCode ) {
993  return i;
994  }
995  }
996 
997  return PAPI_EINVAL;
998 }
999 
1000 /* This function only removes empty EventSets */
1001 
1002 int
1004 {
1005  DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
1006  int i;
1007 
1008  i = ESI->EventSetIndex;
1009 
1011 
1012  _papi_hwi_free_EventSet( ESI );
1013 
1014  /* do bookkeeping for PAPI_EVENTSET_MAP */
1015 
1016  map->dataSlotArray[i] = NULL;
1017  map->availSlots++;
1018  map->fullSlots--;
1019 
1021 
1022  return PAPI_OK;
1023 }
1024 
1025 
1026 /* this function checks if an event is already in an EventSet
1027  Success, return ESI->NativeInfoArray[] index
1028  Fail, return PAPI_ENOEVNT;
1029 */
1030 static int
1032 {
1033  INTDBG( "ENTER: ESI: %p, papi_event: %#x\n", ESI, papi_event);
1034  int i;
1035 
1036  int nevt = _papi_hwi_eventcode_to_native(papi_event);
1037 
1038  /* to find the native event from the native events list */
1039  for( i = 0; i < ESI->NativeCount; i++ ) {
1040  if ( nevt == ESI->NativeInfoArray[i].ni_event ) {
1041  // Also need to check papi event code if set because the same event with different masks
1042  // will generate the same libpfm4 event code (what was checked above). But there will be
1043  // different papi events created for it and they need to be handled separately.
1044  if (papi_event == ESI->NativeInfoArray[i].ni_papi_code) {
1045  INTDBG( "EXIT: event: %#x already mapped at index: %d\n", papi_event, i);
1046  return i;
1047  }
1048  }
1049  }
1050  INTDBG( "EXIT: PAPI_ENOEVNT\n");
1051  return PAPI_ENOEVNT;
1052 }
1053 
1054 /* This function goes through the events in an EventSet's EventInfoArray */
1055 /* And maps each event (whether native or part of a preset) to */
1056 /* an event in the EventSets NativeInfoArray. */
1057 
1058 /* We need to do this every time a native event is added to or removed */
1059 /* from an eventset. */
1060 
1061 /* It is also called after a update controlstate as the components are */
1062 /* allowed to re-arrange the native events to fit hardware constraints. */
1063 
1064 void
1066 {
1067  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);
1068 
1069  int i, event, k, n, preset_index = 0, nevt;
1070  int total_events = ESI->NumberOfEvents;
1071 
1072  event = 0;
1073  for( i = 0; i < total_events; i++ ) {
1074 
1075  /* find the first event that isn't PAPI_NULL */
1076  /* Is this really necessary? --vmw */
1077  while ( ESI->EventInfoArray[event].event_code == ( unsigned int ) PAPI_NULL ) {
1078  event++;
1079  }
1080 
1081  /* If it's a preset */
1082  if ( IS_PRESET(ESI->EventInfoArray[event].event_code) ) {
1083  preset_index = ( int ) ESI->EventInfoArray[event].event_code & PAPI_PRESET_AND_MASK;
1084 
1085  /* walk all sub-events in the preset */
1086  for( k = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT; k++ ) {
1087  nevt = _papi_hwi_presets[preset_index].code[k];
1088  if ( nevt == PAPI_NULL ) {
1089  break;
1090  }
1091 
1092  INTDBG("Looking for subevent %#x\n",nevt);
1093 
1094  /* Match each sub-event to something in the Native List */
1095  for( n = 0; n < ESI->NativeCount; n++ ) {
1096  if ( nevt == ESI->NativeInfoArray[n].ni_papi_code ) {
1097  INTDBG("Found papi event: %#x, &ESI->NativeInfoArray[%d]: %p, ni_event: %#x, ni_position %d\n",
1098  nevt, n, &(ESI->NativeInfoArray[n]), ESI->NativeInfoArray[n].ni_event, ESI->NativeInfoArray[n].ni_position);
1099  ESI->EventInfoArray[event].pos[k] = ESI->NativeInfoArray[n].ni_position;
1100  break;
1101  }
1102  }
1103  }
1104  }
1105  /* If it's a native event */
1106  else if( IS_NATIVE(ESI->EventInfoArray[event].event_code) ) {
1107  nevt = ( int ) ESI->EventInfoArray[event].event_code;
1108 
1109  // get index into native info array for this event
1110  int nidx = event_already_in_eventset( ESI, nevt );
1111  // if not found, then we need to return an error
1112  if (nidx == PAPI_ENOEVNT) {
1113  INTDBG("EXIT: needed event not found\n");
1114  return;
1115  }
1116  ESI->EventInfoArray[event].pos[0] = ESI->NativeInfoArray[nidx].ni_position;
1117  INTDBG("nidx: %d, ni_position: %d\n", nidx, ESI->NativeInfoArray[nidx].ni_position);
1118 
1119  }
1120  /* If it's a user-defined event */
1121  else if ( IS_USER_DEFINED(ESI->EventInfoArray[event].event_code) ) {
1122  preset_index = ( int ) ESI->EventInfoArray[event].event_code & PAPI_UE_AND_MASK;
1123  for ( k = 0; k < PAPI_EVENTS_IN_DERIVED_EVENT; k++ ) {
1124  nevt = user_defined_events[preset_index].code[k];
1125  INTDBG("nevt: %#x, user_defined_events[%d].code[%d]: %#x, code[%d]: %#x\n",
1126  nevt, preset_index, k, user_defined_events[preset_index].code[k], k+1, user_defined_events[preset_index].code[k+1]);
1127 
1128  if ( nevt == PAPI_NULL ) break;
1129 
1130  /* Match each sub-event to something in the Native List */
1131  for ( n = 0; n < ESI->NativeCount; n++ ) {
1132  // if this is the event we are looking for, set its position and exit inner loop to look for next sub-event
1133  if ( _papi_hwi_eventcode_to_native(nevt) == ESI->NativeInfoArray[n].ni_event ) {
1134  ESI->EventInfoArray[event].pos[k] = ESI->NativeInfoArray[n].ni_position;
1135  break;
1136  }
1137  }
1138  }
1139  }
1140  event++;
1141  }
1142  INTDBG("EXIT: \n");
1143  return;
1144 }
1145 
1146 
1147 static int
1149 {
1150  INTDBG("ENTER: ESI: %p, nevt: %#x\n", ESI, nevt);
1151 
1152  int i, max_counters;
1153  int cidx;
1154 
1155  cidx = _papi_hwi_component_index( nevt );
1156  if (cidx<0) return PAPI_ENOCMP;
1157 
1158  max_counters = _papi_hwd[cidx]->cmp_info.num_mpx_cntrs;
1159 
1160  /* to find the native event from the native events list */
1161  for( i = 0; i < max_counters; i++ ) {
1162 // INTDBG("ESI->NativeInfoArray[%d]: %p, ni_event: %#x, ni_papi_event_code: %#x, ni_position: %d, ni_owners: %d\n",
1163 // 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);
1164  if ( nevt == ESI->NativeInfoArray[i].ni_papi_code ) {
1165  ESI->NativeInfoArray[i].ni_owners--;
1166  /* to clean the entry in the nativeInfo array */
1167  if ( ESI->NativeInfoArray[i].ni_owners == 0 ) {
1168  ESI->NativeInfoArray[i].ni_event = -1;
1169  ESI->NativeInfoArray[i].ni_position = -1;
1170  ESI->NativeInfoArray[i].ni_papi_code = -1;
1171  ESI->NativeCount--;
1172  }
1173  INTDBG( "EXIT: nevt: %#x, returned: %d\n", nevt, i);
1174  return i;
1175  }
1176  }
1177  INTDBG( "EXIT: returned: -1\n");
1178  return -1;
1179 }
1180 
1181 /* since update_control_state trashes overflow settings, this puts things
1182  back into balance. */
1183 static int
1185 {
1186  int i, retval = PAPI_OK;
1187 
1188  if ( ESI->overflow.flags & PAPI_OVERFLOW_HARDWARE ) {
1189  for( i = 0; i < ESI->overflow.event_counter; i++ ) {
1190  retval = _papi_hwd[ESI->CmpIdx]->set_overflow( ESI,
1191  ESI->overflow.EventIndex[i],
1192  ESI->overflow.threshold[i] );
1193  if ( retval != PAPI_OK ) {
1194  break;
1195  }
1196  }
1197  }
1198  return retval;
1199 }
1200 
1201 /* this function is called by _papi_hwi_add_event when adding native events
1202  ESI: event set to add the events to
1203  nevnt: pointer to array of native event table indexes to add
1204  size: number of native events to add
1205  out: ???
1206 
1207  return: < 0 = error
1208  0 = no new events added
1209  1 = new events added
1210 */
1211 static int
1212 add_native_events( EventSetInfo_t *ESI, unsigned int *nevt,
1213  int size, EventInfo_t *out )
1214 {
1215  INTDBG ("ENTER: ESI: %p, nevt: %p, size: %d, out: %p\n", ESI, nevt, size, out);
1216  int nidx, i, j, added_events = 0;
1217  int retval, retval2;
1218  int max_counters;
1219  hwd_context_t *context;
1220 
1221  max_counters = _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs;
1222 
1223  /* Walk through the list of native events, adding them */
1224  for( i = 0; i < size; i++ ) {
1225 
1226  /* Check to see if event is already in EventSet */
1227  nidx = event_already_in_eventset( ESI, nevt[i] );
1228 
1229  if ( nidx >= 0 ) {
1230  /* Event is already there. Set position */
1231  out->pos[i] = ESI->NativeInfoArray[nidx].ni_position;
1232  ESI->NativeInfoArray[nidx].ni_owners++;
1233  continue;
1234  }
1235 
1236  /* Event wasn't already there */
1237 
1238  if ( ESI->NativeCount == max_counters ) {
1239 
1240  /* No more room in counters! */
1241  for( j = 0; j < i; j++ ) {
1242  if ( ( nidx = add_native_fail_clean( ESI, nevt[j] ) ) >= 0 ) {
1243  out->pos[j] = -1;
1244  continue;
1245  }
1246  INTDBG( "should not happen!\n" );
1247  }
1248  INTDBG( "EXIT: counters are full!\n" );
1249  return PAPI_ECOUNT;
1250  }
1251 
1252  /* there is an empty slot for the native event; */
1253  /* initialize the native index for the new added event */
1254  INTDBG( "Adding nevt[%d]: %#x, ESI->NativeInfoArray[%d]: %p, Component: %d\n",
1255  i, nevt[i], ESI->NativeCount, &ESI->NativeInfoArray[ESI->NativeCount], ESI->CmpIdx );
1256  ESI->NativeInfoArray[ESI->NativeCount].ni_event =
1258  ESI->NativeInfoArray[ESI->NativeCount].ni_papi_code = nevt[i];
1259 
1260  ESI->NativeInfoArray[ESI->NativeCount].ni_owners = 1;
1261  ESI->NativeCount++;
1262  added_events++;
1263  }
1264 
1265  INTDBG("added_events: %d\n", added_events);
1266 
1267  /* if we added events we need to tell the component so it */
1268  /* can add them too. */
1269  if ( added_events ) {
1270  /* get the context we should use for this event set */
1271  context = _papi_hwi_get_context( ESI, NULL );
1272 
1273  if ( _papi_hwd[ESI->CmpIdx]->allocate_registers( ESI ) == PAPI_OK ) {
1274 
1275  retval = _papi_hwd[ESI->CmpIdx]->update_control_state( ESI->ctl_state,
1276  ESI->NativeInfoArray,
1277  ESI->NativeCount,
1278  context);
1279  if ( retval != PAPI_OK ) {
1280 clean:
1281  for( i = 0; i < size; i++ ) {
1282  if ( ( nidx = add_native_fail_clean( ESI, nevt[i] ) ) >= 0 ) {
1283  out->pos[i] = -1;
1284  continue;
1285  }
1286  INTDBG( "should not happen!\n" );
1287  }
1288  /* re-establish the control state after the previous error */
1289  retval2 = _papi_hwd[ESI->CmpIdx]->update_control_state(
1290  ESI->ctl_state,
1291  ESI->NativeInfoArray,
1292  ESI->NativeCount,
1293  context);
1294  if ( retval2 != PAPI_OK ) {
1295  PAPIERROR("update_control_state failed to re-establish working events!" );
1296  INTDBG( "EXIT: update_control_state returned: %d\n", retval2);
1297  return retval2;
1298  }
1299  INTDBG( "EXIT: update_control_state returned: %d\n", retval);
1300  return retval;
1301  }
1302  INTDBG( "EXIT: update_control_state returned: %d, we return: 1 (need remap)\n", retval);
1303  return 1; /* need remap */
1304  } else {
1305  retval = PAPI_EMISC;
1306  goto clean;
1307  }
1308  }
1309  INTDBG( "EXIT: PAPI_OK\n");
1310  return PAPI_OK;
1311 }
1312 
1313 
1314 int
1315 _papi_hwi_add_event( EventSetInfo_t * ESI, int EventCode )
1316 {
1317  INTDBG("ENTER: ESI: %p (%d), EventCode: %#x\n", ESI, ESI->EventSetIndex, EventCode);
1318 
1319  int i, j, thisindex, remap, retval = PAPI_OK;
1320  int cidx;
1321 
1322  cidx=_papi_hwi_component_index( EventCode );
1323  if (cidx<0) return PAPI_ENOCMP;
1324 
1325  /* Sanity check that the new EventCode is from the same component */
1326  /* as previous events. */
1327 
1328  if ( ESI->CmpIdx < 0 ) {
1329  if ( ( retval = _papi_hwi_assign_eventset( ESI, cidx)) != PAPI_OK ) {
1330  INTDBG("EXIT: Error assigning eventset to component index %d\n", cidx);
1331  return retval;
1332  }
1333  } else {
1334  if ( ESI->CmpIdx != cidx ) {
1335  INTDBG("EXIT: Event is not valid for component index %d\n", cidx);
1336  return PAPI_EINVAL;
1337  }
1338  }
1339 
1340  /* Make sure the event is not present and get the next free slot. */
1341  thisindex = get_free_EventCodeIndex( ESI, ( unsigned int ) EventCode );
1342  if ( thisindex < PAPI_OK ) {
1343  return thisindex;
1344  }
1345 
1346  INTDBG("Adding event to slot %d of EventSet %d\n",thisindex,ESI->EventSetIndex);
1347 
1348  /* If it is a software MPX EventSet, add it to the multiplex data structure */
1349  /* and this thread's multiplex list */
1350 
1351  if ( !_papi_hwi_is_sw_multiplex( ESI ) ) {
1352 
1353  /* Handle preset case */
1354  if ( IS_PRESET(EventCode) ) {
1355  int count;
1356  int preset_index = EventCode & ( int ) PAPI_PRESET_AND_MASK;
1357 
1358  /* Check if it's within the valid range */
1359  if ( ( preset_index < 0 ) || ( preset_index >= PAPI_MAX_PRESET_EVENTS ) ) {
1360  return PAPI_EINVAL;
1361  }
1362 
1363  /* count the number of native events in this preset */
1364  count = ( int ) _papi_hwi_presets[preset_index].count;
1365 
1366  /* Check if event exists */
1367  if ( !count ) {
1368  return PAPI_ENOEVNT;
1369  }
1370 
1371  /* check if the native events have been used as overflow events */
1372  /* this is not allowed */
1373  if ( ESI->state & PAPI_OVERFLOWING ) {
1374  for( i = 0; i < count; i++ ) {
1375  for( j = 0; j < ESI->overflow.event_counter; j++ ) {
1376  if ( ESI->overflow.EventCode[j] ==(int)
1377  ( _papi_hwi_presets[preset_index].code[i] ) ) {
1378  return PAPI_ECNFLCT;
1379  }
1380  }
1381  }
1382  }
1383 
1384  /* Try to add the preset. */
1385 
1386  remap = add_native_events( ESI,
1387  _papi_hwi_presets[preset_index].code,
1388  count, &ESI->EventInfoArray[thisindex] );
1389  if ( remap < 0 ) {
1390  return remap;
1391  }
1392  else {
1393  /* Fill in the EventCode (machine independent) information */
1394  ESI->EventInfoArray[thisindex].event_code =
1395  ( unsigned int ) EventCode;
1396  ESI->EventInfoArray[thisindex].derived =
1397  _papi_hwi_presets[preset_index].derived_int;
1398  ESI->EventInfoArray[thisindex].ops =
1399  _papi_hwi_presets[preset_index].postfix;
1400  ESI->NumberOfEvents++;
1402 
1403  }
1404  }
1405  /* Handle adding Native events */
1406  else if ( IS_NATIVE(EventCode) ) {
1407 
1408  /* Check if native event exists */
1409  if ( _papi_hwi_query_native_event( ( unsigned int ) EventCode ) != PAPI_OK ) {
1410  return PAPI_ENOEVNT;
1411  }
1412 
1413  /* check if the native events have been used as overflow events */
1414  /* This is not allowed */
1415  if ( ESI->state & PAPI_OVERFLOWING ) {
1416  for( j = 0; j < ESI->overflow.event_counter; j++ ) {
1417  if ( EventCode == ESI->overflow.EventCode[j] ) {
1418  return PAPI_ECNFLCT;
1419  }
1420  }
1421  }
1422 
1423  /* Try to add the native event. */
1424 
1425  remap = add_native_events( ESI, (unsigned int *)&EventCode, 1,
1426  &ESI->EventInfoArray[thisindex] );
1427 
1428  if ( remap < 0 ) {
1429  return remap;
1430  } else {
1431 
1432  /* Fill in the EventCode (machine independent) information */
1433  ESI->EventInfoArray[thisindex].event_code =
1434  ( unsigned int ) EventCode;
1435  ESI->NumberOfEvents++;
1437 
1438  }
1439  } else if ( IS_USER_DEFINED( EventCode ) ) {
1440  int count;
1441  int index = EventCode & PAPI_UE_AND_MASK;
1442 
1443  if ( index < 0 || index >= user_defined_events_count )
1444  return ( PAPI_EINVAL );
1445 
1446  count = ( int ) user_defined_events[index].count;
1447 
1448  for ( i = 0; i < count; i++ ) {
1449  for ( j = 0; j < ESI->overflow.event_counter; j++ ) {
1450  if ( ESI->overflow.EventCode[j] ==
1451  (int)(user_defined_events[index].code[i]) ) {
1452  return ( PAPI_EBUG );
1453  }
1454  }
1455  }
1456 
1457  remap = add_native_events( ESI,
1458  user_defined_events[index].code,
1459  count, &ESI->EventInfoArray[thisindex] );
1460 
1461  if ( remap < 0 ) {
1462  return remap;
1463  } else {
1464  ESI->EventInfoArray[thisindex].event_code = (unsigned int) EventCode;
1465  ESI->EventInfoArray[thisindex].derived = user_defined_events[index].derived_int;
1466  ESI->EventInfoArray[thisindex].ops = user_defined_events[index].postfix;
1467  ESI->NumberOfEvents++;
1469  }
1470  } else {
1471 
1472  /* not Native, Preset, or User events */
1473 
1474  return PAPI_EBUG;
1475  }
1476  }
1477  else {
1478 
1479  /* Multiplexing is special. See multiplex.c */
1480 
1481  retval = mpx_add_event( &ESI->multiplex.mpx_evset, EventCode,
1482  ESI->domain.domain,
1483  ESI->granularity.granularity );
1484 
1485 
1486  if ( retval < PAPI_OK ) {
1487  return retval;
1488  }
1489 
1490  /* Relevant (???) */
1491  ESI->EventInfoArray[thisindex].event_code = ( unsigned int ) EventCode;
1492  ESI->EventInfoArray[thisindex].derived = NOT_DERIVED;
1493 
1494  ESI->NumberOfEvents++;
1495 
1496  /* event is in the EventInfoArray but not mapped to the NativeEvents */
1497  /* this causes issues if you try to set overflow on the event. */
1498  /* in theory this wouldn't matter anyway. */
1499  }
1500 
1501  /* reinstate the overflows if any */
1502  retval=update_overflow( ESI );
1503 
1504  return retval;
1505 }
1506 
1507 static int
1509 {
1510  INTDBG( "Entry: ESI: %p, nevt: %p, size: %d\n", ESI, nevt, size);
1512  hwd_context_t *context;
1513  int i, j, zero = 0, retval;
1514 
1515  /* Remove the references to this event from the native events:
1516  for all the metrics in this event,
1517  compare to each native event in this event set,
1518  and decrement owners if they match */
1519  for( i = 0; i < size; i++ ) {
1520  int cevt = _papi_hwi_eventcode_to_native(nevt[i]);
1521 // INTDBG( "nevt[%d]: %#x, cevt: %#x\n", i, nevt[i], cevt);
1522  for( j = 0; j < ESI->NativeCount; j++ ) {
1523  if ((native[j].ni_event == cevt) && (native[j].ni_papi_code == nevt[i]) ) {
1524 // INTDBG( "native[%d]: %p, ni_papi_code: %#x, ni_event: %#x, ni_position: %d, ni_owners: %d\n",
1525 // j, &(native[j]), native[j].ni_papi_code, native[j].ni_event, native[j].ni_position, native[j].ni_owners);
1526  native[j].ni_owners--;
1527  if ( native[j].ni_owners == 0 ) {
1528  zero++;
1529  }
1530  break;
1531  }
1532  }
1533  }
1534 
1535  /* Remove any native events from the array if owners dropped to zero.
1536  The NativeInfoArray must be dense, with no empty slots, so if we
1537  remove an element, we must compact the list */
1538  for( i = 0; i < ESI->NativeCount; i++ ) {
1539 
1540  if ( native[i].ni_event == -1 ) continue;
1541 
1542  if ( native[i].ni_owners == 0 ) {
1543  int copy = 0;
1544  int sz = _papi_hwd[ESI->CmpIdx]->size.reg_value;
1545  for( j = ESI->NativeCount - 1; j > i; j-- ) {
1546  if ( native[j].ni_event == -1 || native[j].ni_owners == 0 ) continue;
1547  else {
1548  /* copy j into i */
1549  native[i].ni_event = native[j].ni_event;
1550  native[i].ni_position = native[j].ni_position;
1551  native[i].ni_owners = native[j].ni_owners;
1552  /* copy opaque [j].ni_bits to [i].ni_bits */
1553  memcpy( native[i].ni_bits, native[j].ni_bits, ( size_t ) sz );
1554  /* reset j to initialized state */
1555  native[j].ni_event = -1;
1556  native[j].ni_position = -1;
1557  native[j].ni_owners = 0;
1558  copy++;
1559  break;
1560  }
1561  }
1562 
1563  if ( copy == 0 ) {
1564  /* set this structure back to empty state */
1565  /* ni_owners is already 0 and contents of ni_bits doesn't matter */
1566  native[i].ni_event = -1;
1567  native[i].ni_position = -1;
1568  }
1569  }
1570  }
1571 
1572  INTDBG( "ESI->NativeCount: %d, zero: %d\n", ESI->NativeCount, zero);
1573 
1574  /* to reset hwd_control_state values */
1575  ESI->NativeCount -= zero;
1576 
1577  /* If we removed any elements,
1578  clear the now empty slots, reinitialize the index, and update the count.
1579  Then send the info down to the component to update the hwd control structure. */
1580  retval = PAPI_OK;
1581  if ( zero ) {
1582  /* get the context we should use for this event set */
1583  context = _papi_hwi_get_context( ESI, NULL );
1585  native, ESI->NativeCount, context);
1586  if ( retval == PAPI_OK )
1587  retval = update_overflow( ESI );
1588  }
1589  return ( retval );
1590 }
1591 
1592 int
1594 {
1595  int j = 0, retval, thisindex;
1596  EventInfo_t *array;
1597 
1598  thisindex =
1599  _papi_hwi_lookup_EventCodeIndex( ESI, ( unsigned int ) EventCode );
1600  if ( thisindex < PAPI_OK )
1601  return ( thisindex );
1602 
1603  /* If it is a MPX EventSet, remove it from the multiplex data structure and
1604  this threads multiplex list */
1605 
1606  if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
1607  retval = mpx_remove_event( &ESI->multiplex.mpx_evset, EventCode );
1608  if ( retval < PAPI_OK )
1609  return ( retval );
1610  } else
1611  /* Remove the events hardware dependent stuff from the EventSet */
1612  {
1613  if ( IS_PRESET(EventCode) ) {
1614  int preset_index = EventCode & PAPI_PRESET_AND_MASK;
1615 
1616  /* Check if it's within the valid range */
1617  if ( ( preset_index < 0 ) ||
1618  ( preset_index >= PAPI_MAX_PRESET_EVENTS ) )
1619  return PAPI_EINVAL;
1620 
1621  /* Check if event exists */
1622  if ( !_papi_hwi_presets[preset_index].count )
1623  return PAPI_ENOEVNT;
1624 
1625  /* Remove the preset event. */
1626  for ( j = 0; _papi_hwi_presets[preset_index].code[j] != (unsigned int)PAPI_NULL;
1627  j++ );
1628  retval = remove_native_events( ESI, ( int * )_papi_hwi_presets[preset_index].code, j );
1629  if ( retval != PAPI_OK )
1630  return ( retval );
1631  } else if ( IS_NATIVE(EventCode) ) {
1632  /* Check if native event exists */
1633  if ( _papi_hwi_query_native_event( ( unsigned int ) EventCode ) !=
1634  PAPI_OK )
1635  return PAPI_ENOEVNT;
1636 
1637  /* Remove the native event. */
1638  retval = remove_native_events( ESI, &EventCode, 1 );
1639  if ( retval != PAPI_OK )
1640  return ( retval );
1641  } else if ( IS_USER_DEFINED( EventCode ) ) {
1642  int index = EventCode & PAPI_UE_AND_MASK;
1643 
1644  if ( (index < 0) || (index >= user_defined_events_count) )
1645  return ( PAPI_EINVAL );
1646 
1647  for( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT &&
1648  user_defined_events[index].code[j] != 0; j++ ) {
1649  retval = remove_native_events( ESI, ( int * )user_defined_events[index].code, j);
1650 
1651  if ( retval != PAPI_OK )
1652  return ( retval );
1653  }
1654  } else
1655  return ( PAPI_ENOEVNT );
1656  }
1657  array = ESI->EventInfoArray;
1658 
1659  /* Compact the Event Info Array list if it's not the last event */
1660  /* clear the newly empty slot in the array */
1661  for ( ; thisindex < ESI->NumberOfEvents - 1; thisindex++ )
1662  array[thisindex] = array[thisindex + 1];
1663 
1664 
1665  array[thisindex].event_code = ( unsigned int ) PAPI_NULL;
1666  for ( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ )
1667  array[thisindex].pos[j] = PAPI_NULL;
1668  array[thisindex].ops = NULL;
1669  array[thisindex].derived = NOT_DERIVED;
1670  ESI->NumberOfEvents--;
1671 
1672  return ( PAPI_OK );
1673 }
1674 
1675 int
1677  long long *values )
1678 {
1679  INTDBG("ENTER: context: %p, ESI: %p, values: %p\n", context, ESI, values);
1680  int retval;
1681  long long *dp = NULL;
1682  int i, index;
1683 
1684  retval = _papi_hwd[ESI->CmpIdx]->read( context, ESI->ctl_state,
1685  &dp, ESI->state );
1686  if ( retval != PAPI_OK ) {
1687  INTDBG("EXIT: retval: %d\n", retval);
1688  return retval;
1689  }
1690 
1691  /* This routine distributes hardware counters to software counters in the
1692  order that they were added. Note that the higher level
1693  EventInfoArray[i] entries may not be contiguous because the user
1694  has the right to remove an event.
1695  But if we do compaction after remove event, this function can be
1696  changed.
1697  */
1698 
1699  for ( i = 0; i != ESI->NumberOfEvents; i++ ) {
1700 
1701  index = ESI->EventInfoArray[i].pos[0];
1702 
1703  if ( index == -1 )
1704  continue;
1705 
1706  INTDBG( "ESI->EventInfoArray: %p, pos[%d]: %d, dp[%d]: %lld, derived[%d]: %#x\n", ESI->EventInfoArray, i, index, index, dp[index], i, ESI->EventInfoArray[i].derived );
1707 
1708  /* If this is not a derived event */
1709 
1710  if ( ESI->EventInfoArray[i].derived == NOT_DERIVED ) {
1711  values[i] = dp[index];
1712  INTDBG( "value: %#llx\n", values[i] );
1713  } else { /* If this is a derived event */
1714  values[i] = handle_derived( &ESI->EventInfoArray[i], dp );
1715 #ifdef DEBUG
1716  if ( values[i] < ( long long ) 0 ) {
1717  INTDBG( "Derived Event is negative!!: %lld\n", values[i] );
1718  }
1719  INTDBG( "derived value: %#llx \n", values[i] );
1720 #endif
1721  }
1722  }
1723 
1724  INTDBG("EXIT: PAPI_OK\n");
1725  return PAPI_OK;
1726 }
1727 
1728 int
1730 {
1731  int i, j, num_cntrs, retval;
1732  hwd_context_t *context;
1733  int EventCode;
1735  if ( !_papi_hwi_invalid_cmp( ESI->CmpIdx ) ) {
1736  num_cntrs = _papi_hwd[ESI->CmpIdx]->cmp_info.num_mpx_cntrs;
1737 
1738  for(i=0;i<num_cntrs;i++) {
1739 
1740  EventCode=ESI->EventInfoArray[i].event_code;
1741 
1742  /* skip if event not there */
1743  if ( EventCode == PAPI_NULL ) continue;
1744 
1745  /* If it is a MPX EventSet, remove it from the multiplex */
1746  /* data structure and this thread's multiplex list */
1747 
1748  if ( _papi_hwi_is_sw_multiplex( ESI ) ) {
1749  retval = mpx_remove_event( &ESI->multiplex.mpx_evset, EventCode );
1750  if ( retval < PAPI_OK )
1751  return retval;
1752  } else {
1753 
1754  native = ESI->NativeInfoArray;
1755 
1756  /* clear out ESI->NativeInfoArray */
1757  /* do we really need to do this, seeing as we free() it later? */
1758 
1759  for( j = 0; j < ESI->NativeCount; j++ ) {
1760  native[j].ni_event = -1;
1761  native[j].ni_position = -1;
1762  native[j].ni_owners = 0;
1763  /* native[j].ni_bits?? */
1764  }
1765  }
1766 
1767  /* do we really need to do this, seeing as we free() it later? */
1768  ESI->EventInfoArray[i].event_code= ( unsigned int ) PAPI_NULL;
1769  for( j = 0; j < PAPI_EVENTS_IN_DERIVED_EVENT; j++ ) {
1770  ESI->EventInfoArray[i].pos[j] = PAPI_NULL;
1771  }
1772  ESI->EventInfoArray[i].ops = NULL;
1774  }
1775 
1776  context = _papi_hwi_get_context( ESI, NULL );
1777  /* calling with count of 0 equals a close? */
1778  retval = _papi_hwd[ESI->CmpIdx]->update_control_state( ESI->ctl_state,
1779  NULL, 0, context);
1780  if (retval!=PAPI_OK) {
1781  return retval;
1782  }
1783  }
1784 
1785  ESI->CmpIdx = -1;
1786  ESI->NumberOfEvents = 0;
1787  ESI->NativeCount = 0;
1788 
1789  if ( ( ESI->state & PAPI_MULTIPLEXING ) && ESI->multiplex.mpx_evset )
1790  papi_free( ESI->multiplex.mpx_evset );
1791 
1792  if ( ( ESI->state & PAPI_CPU_ATTACH ) && ESI->CpuInfo )
1794 
1795  if ( ESI->ctl_state )
1796  papi_free( ESI->ctl_state );
1797 
1798  if ( ESI->sw_stop )
1799  papi_free( ESI->sw_stop );
1800 
1801  if ( ESI->hw_start )
1802  papi_free( ESI->hw_start );
1803 
1804  if ( ESI->EventInfoArray )
1805  papi_free( ESI->EventInfoArray );
1806 
1807  if ( ESI->NativeInfoArray )
1808  papi_free( ESI->NativeInfoArray );
1809 
1810  if ( ESI->NativeBits )
1811  papi_free( ESI->NativeBits );
1812 
1813  if ( ESI->overflow.deadline )
1814  papi_free( ESI->overflow.deadline );
1815 
1816  if ( ESI->profile.prof )
1817  papi_free( ESI->profile.prof );
1818 
1819  ESI->ctl_state = NULL;
1820  ESI->sw_stop = NULL;
1821  ESI->hw_start = NULL;
1822  ESI->EventInfoArray = NULL;
1823  ESI->NativeInfoArray = NULL;
1824  ESI->NativeBits = NULL;
1825 
1826  memset( &ESI->domain, 0x0, sizeof(EventSetDomainInfo_t) );
1827  memset( &ESI->granularity, 0x0, sizeof(EventSetGranularityInfo_t) );
1828  memset( &ESI->overflow, 0x0, sizeof(EventSetOverflowInfo_t) );
1829  memset( &ESI->multiplex, 0x0, sizeof(EventSetMultiplexInfo_t) );
1830  memset( &ESI->attach, 0x0, sizeof(EventSetAttachInfo_t) );
1831  memset( &ESI->cpu, 0x0, sizeof(EventSetCpuInfo_t) );
1832  memset( &ESI->profile, 0x0, sizeof(EventSetProfileInfo_t) );
1833  memset( &ESI->inherit, 0x0, sizeof(EventSetInheritInfo_t) );
1834 
1835  ESI->CpuInfo = NULL;
1836 
1837  return PAPI_OK;
1838 }
1839 
1840 int
1842 {
1843  int retval, i, j = 0, *mpxlist = NULL;
1844  EventSetInfo_t *ESI = mpx->ESI;
1845  int flags = mpx->flags;
1846 
1847  /* If there are any events in the EventSet,
1848  convert them to multiplex events */
1849 
1850  if ( ESI->NumberOfEvents ) {
1851 
1852  mpxlist =
1853  ( int * ) papi_malloc( sizeof ( int ) *
1854  ( size_t ) ESI->NumberOfEvents );
1855  if ( mpxlist == NULL )
1856  return ( PAPI_ENOMEM );
1857 
1858  /* Build the args to MPX_add_events(). */
1859 
1860  /* Remember the EventInfoArray can be sparse
1861  and the data can be non-contiguous */
1862 
1863  for ( i = 0; i < EventInfoArrayLength( ESI ); i++ )
1864  if ( ESI->EventInfoArray[i].event_code !=
1865  ( unsigned int ) PAPI_NULL )
1866  mpxlist[j++] = ( int ) ESI->EventInfoArray[i].event_code;
1867 
1868  /* Resize the EventInfo_t array */
1869 
1870  if ( ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex == 0 ) ||
1871  ( ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex ) &&
1872  ( flags & PAPI_MULTIPLEX_FORCE_SW ) ) ) {
1873  retval =
1874  MPX_add_events( &ESI->multiplex.mpx_evset, mpxlist, j,
1875  ESI->domain.domain,
1876  ESI->granularity.granularity );
1877  if ( retval != PAPI_OK ) {
1878  papi_free( mpxlist );
1879  return ( retval );
1880  }
1881  }
1882 
1883  papi_free( mpxlist );
1884  }
1885 
1886  /* Update the state before initialization! */
1887 
1888  ESI->state |= PAPI_MULTIPLEXING;
1889  if ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex &&
1890  ( flags & PAPI_MULTIPLEX_FORCE_SW ) )
1892  ESI->multiplex.ns = ( int ) mpx->ns;
1893 
1894  return ( PAPI_OK );
1895 }
1896 
1897 #include "components_config.h"
1898 
1899 int papi_num_components = ( sizeof ( _papi_hwd ) / sizeof ( *_papi_hwd ) ) - 1;
1900 
1901 /*
1902  * Routine that initializes all available components.
1903  * A component is available if a pointer to its info vector
1904  * appears in the NULL terminated_papi_hwd table.
1905  */
1906 int
1908 {
1909  int retval, i = 0;
1910 
1912  if ( retval != PAPI_OK ) {
1913  return retval;
1914  }
1915 
1916  while ( _papi_hwd[i] ) {
1917 
1918  retval = _papi_hwi_innoculate_vector( _papi_hwd[i] );
1919  if ( retval != PAPI_OK ) {
1920  return retval;
1921  }
1922 
1923  /* We can be disabled by user before init */
1924  if (!_papi_hwd[i]->cmp_info.disabled) {
1925  retval = _papi_hwd[i]->init_component( i );
1927 
1928  /* Do some sanity checking */
1929  if (retval==PAPI_OK) {
1930  if (_papi_hwd[i]->cmp_info.num_cntrs >
1932  fprintf(stderr,"Warning! num_cntrs is more than num_mpx_cntrs\n");
1933  }
1934 
1935  }
1936  }
1937 
1938  i++;
1939  }
1940  return PAPI_OK;
1941 }
1942 
1943 /* Machine info struct initialization using defaults */
1944 /* See _papi_mdi definition in papi_internal.h */
1945 
1946 int
1948 {
1949 
1950  int retval;
1951 
1952  memset(&_papi_hwi_system_info,0x0,sizeof( _papi_hwi_system_info ));
1953 
1954  memset( _papi_hwi_using_signal,0x0,sizeof( _papi_hwi_using_signal ));
1955 
1956  /* Global struct to maintain EventSet mapping */
1957  retval = allocate_eventset_map( &_papi_hwi_system_info.global_eventset_map );
1958  if ( retval != PAPI_OK ) {
1959  return retval;
1960  }
1961 
1962  _papi_hwi_system_info.pid = 0; /* Process identifier */
1963 
1964  /* PAPI_hw_info_t struct */
1965  memset(&(_papi_hwi_system_info.hw_info),0x0,sizeof(PAPI_hw_info_t));
1966 
1967  return PAPI_OK;
1968 }
1969 
1970 void
1972 {
1974 
1976 
1978 
1979  papi_free( _papi_hwi_system_info.global_eventset_map.dataSlotArray );
1980  memset( &_papi_hwi_system_info.global_eventset_map,
1981  0x00, sizeof ( DynamicArray_t ) );
1982 
1984 
1985  if ( _papi_hwi_system_info.shlib_info.map ) {
1986  papi_free( _papi_hwi_system_info.shlib_info.map );
1987  }
1988  memset( &_papi_hwi_system_info, 0x0, sizeof ( _papi_hwi_system_info ) );
1989 
1990 }
1991 
1992 
1993 
1994 void
1995 _papi_hwi_dummy_handler( int EventSet, void *address, long long overflow_vector,
1996  void *context )
1997 {
1998  /* This function is not used and shouldn't be called. */
1999  ( void ) EventSet; /*unused */
2000  ( void ) address; /*unused */
2001  ( void ) overflow_vector; /*unused */
2002  ( void ) context; /*unused */
2003  return;
2004 }
2005 
2006 static long long
2007 handle_derived_add( int *position, long long *from )
2008 {
2009  int pos, i;
2010  long long retval = 0;
2011 
2012  i = 0;
2013  while ( i < PAPI_EVENTS_IN_DERIVED_EVENT ) {
2014  pos = position[i++];
2015  if ( pos == PAPI_NULL )
2016  break;
2017  INTDBG( "Compound event, adding %lld to %lld\n", from[pos], retval );
2018  retval += from[pos];
2019  }
2020  return ( retval );
2021 }
2022 
2023 static long long
2024 handle_derived_subtract( int *position, long long *from )
2025 {
2026  int pos, i;
2027  long long retval = from[position[0]];
2028 
2029  i = 1;
2030  while ( i < PAPI_EVENTS_IN_DERIVED_EVENT ) {
2031  pos = position[i++];
2032  if ( pos == PAPI_NULL )
2033  break;
2034  INTDBG( "Compound event, subtracting pos=%d %lld from %lld\n", pos,
2035  from[pos], retval );
2036  retval -= from[pos];
2037  }
2038  return ( retval );
2039 }
2040 
2041 static long long
2042 units_per_second( long long units, long long cycles )
2043 {
2044  return ( ( units * (long long) _papi_hwi_system_info.hw_info.cpu_max_mhz *
2045  (long long) 1000000 ) / cycles );
2046 }
2047 
2048 static long long
2049 handle_derived_ps( int *position, long long *from )
2050 {
2051  return ( units_per_second( from[position[1]], from[position[0]] ) );
2052 }
2053 static long long
2054 handle_derived_add_ps( int *position, long long *from )
2055 {
2056  long long tmp = handle_derived_add( position + 1, from );
2057  return ( units_per_second( tmp, from[position[0]] ) );
2058 }
2059 
2060 /* this function implement postfix calculation, it reads in a string where I use:
2061  | as delimiter
2062  N2 indicate No. 2 native event in the derived preset
2063  +, -, *, /, % as operator
2064  # as MHZ(million hz) got from _papi_hwi_system_info.hw_info.cpu_max_mhz*1000000.0
2065 
2066  Haihang (you@cs.utk.edu)
2067 */
2068 static long long
2069 _papi_hwi_postfix_calc( EventInfo_t * evi, long long *hw_counter )
2070 {
2071  INTDBG("ENTER: evi: %p, evi->ops: %p (%s), evi->pos[0]: %d, evi->pos[1]: %d, hw_counter: %p (%lld %lld)\n", evi, evi->ops, evi->ops, evi->pos[0], evi->pos[1], hw_counter, hw_counter[0], hw_counter[1]);
2072  char *point = evi->ops, operand[16];
2074  int i, top = 0;
2075 
2076  memset(&stack,0,PAPI_EVENTS_IN_DERIVED_EVENT*sizeof(double));
2077 
2078  while ( *point != '\0' ) {
2079  if ( *point == '|' ) { /* ignore leading and consecutive '|' characters */
2080  point++;
2081  } else if ( *point == 'N' ) { /* to get count for each native event */
2082  i = 0;
2083  point++;
2084  do {
2085  operand[i] = *point;
2086  point++;
2087  i++;
2088  } while ( *point != '|' );
2089  operand[i] = '\0';
2090  stack[top] = ( double ) hw_counter[evi->pos[atoi( operand )]];
2091  top++;
2092  point++;
2093  } else if ( *point == '#' ) { /* to get mhz, ignore the rest char's */
2094  stack[top] = _papi_hwi_system_info.hw_info.cpu_max_mhz * 1000000.0;
2095  top++;
2096  do {
2097  point++;
2098  } while ( *point != '|' );
2099  point++;
2100  } else if ( isdigit( *point ) ) { /* to get integer, I suppose only integer will be used,
2101  no error check here, please only use integer */
2102  i = 0;
2103  do {
2104  operand[i] = *point;
2105  point++;
2106  i++;
2107  } while ( *point != '|' );
2108  operand[i] = '\0';
2109  stack[top] = atoi( operand );
2110  top++;
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 if ( *point == '-' ) { /* - calculation */
2120  stack[top - 2] -= stack[top - 1];
2121  top--;
2122  do {
2123  point++;
2124  } while ( *point != '|' );
2125  point++;
2126  } else if ( *point == '*' ) { /* * calculation */
2127  stack[top - 2] *= stack[top - 1];
2128  top--;
2129  do {
2130  point++;
2131  } while ( *point != '|' );
2132  point++;
2133  } else if ( *point == '/' ) { /* / calculation */
2134  stack[top - 2] /= stack[top - 1];
2135  top--;
2136  do {
2137  point++;
2138  } while ( *point != '|' );
2139  point++;
2140  } else { /* do nothing */
2141  do {
2142  point++;
2143  } while ( *point != '|' );
2144  point++;
2145  }
2146  }
2147  INTDBG("EXIT: stack[0]: %lld\n", (long long)stack[0]);
2148  return ( long long ) stack[0];
2149 }
2150 
2151 static long long
2152 handle_derived( EventInfo_t * evi, long long *from )
2153 {
2154  INTDBG("ENTER: evi: %p, evi->derived: %d, from: %p\n", evi, evi->derived, from);
2155  switch ( evi->derived ) {
2156  case DERIVED_ADD:
2157  return ( handle_derived_add( evi->pos, from ) );
2158  case DERIVED_ADD_PS:
2159  return ( handle_derived_add_ps( evi->pos, from ) );
2160  case DERIVED_SUB:
2161  return ( handle_derived_subtract( evi->pos, from ) );
2162  case DERIVED_PS:
2163  return ( handle_derived_ps( evi->pos, from ) );
2164  case DERIVED_POSTFIX:
2165  return ( _papi_hwi_postfix_calc( evi, from ) );
2166  case DERIVED_CMPD: /* This type has existed for a long time, but was never implemented.
2167  Probably because its a no-op. However, if it's in a header, it
2168  should be supported. As I found out when I implemented it in
2169  Pentium 4 for testing...dkt */
2170  return ( from[evi->pos[0]] );
2171  default:
2172  PAPIERROR( "BUG! Unknown derived command %d, returning 0", evi->derived );
2173  INTDBG("EXIT: Unknown derived command %d\n", evi->derived);
2174  return ( ( long long ) 0 );
2175  }
2176 }
2177 
2178 
2179 /* table matching derived types to derived strings.
2180  used by get_info, encode_event, xml translator
2181 */
2183  {NOT_DERIVED, "NOT_DERIVED", "Do nothing"},
2184  {DERIVED_ADD, "DERIVED_ADD", "Add counters"},
2185  {DERIVED_PS, "DERIVED_PS",
2186  "Divide by the cycle counter and convert to seconds"},
2187  {DERIVED_ADD_PS, "DERIVED_ADD_PS",
2188  "Add 2 counters then divide by the cycle counter and xl8 to secs."},
2189  {DERIVED_CMPD, "DERIVED_CMPD",
2190  "Event lives in first counter but takes 2 or more codes"},
2191  {DERIVED_SUB, "DERIVED_SUB", "Sub all counters from first counter"},
2192  {DERIVED_POSTFIX, "DERIVED_POSTFIX",
2193  "Process counters based on specified postfix string"},
2194  {DERIVED_INFIX, "DERIVED_INFIX",
2195  "Process counters based on specified infix string"},
2196  {-1, NULL, NULL}
2197 };
2198 
2199 /* _papi_hwi_derived_type:
2200  Helper routine to extract a derived type from a derived string
2201  returns type value if found, otherwise returns -1
2202 */
2203 int
2204 _papi_hwi_derived_type( char *tmp, int *code )
2205 {
2206  int i = 0;
2207  while ( _papi_hwi_derived[i].name != NULL ) {
2208  if ( strcasecmp( tmp, _papi_hwi_derived[i].name ) == 0 ) {
2209  *code = _papi_hwi_derived[i].value;
2210  return PAPI_OK;
2211  }
2212  i++;
2213  }
2214  INTDBG( "Invalid derived string %s\n", tmp );
2215  return PAPI_EINVAL;
2216 }
2217 
2218 
2219 /* _papi_hwi_derived_string:
2220  Helper routine to extract a derived string from a derived type
2221  copies derived type string into derived if found,
2222  otherwise returns PAPI_EINVAL
2223 */
2224 static int
2225 _papi_hwi_derived_string( int type, char *derived, int len )
2226 {
2227  int j;
2228 
2229  for ( j = 0; _papi_hwi_derived[j].value != -1; j++ ) {
2230  if ( _papi_hwi_derived[j].value == type ) {
2231  strncpy( derived, _papi_hwi_derived[j].name, ( size_t )\
2232  len );
2233  return PAPI_OK;
2234  }
2235  }
2236  INTDBG( "Invalid derived type %d\n", type );
2237  return PAPI_EINVAL;
2238 }
2239 
2240 
2241 /* _papi_hwi_get_preset_event_info:
2242  Assumes EventCode contains a valid preset code.
2243  But defensive programming says check for NULL pointers.
2244  Returns a filled in PAPI_event_info_t structure containing
2245  descriptive strings and values for the specified preset event.
2246 */
2247 int
2249 {
2250  INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info);
2251 
2252  int i = EventCode & PAPI_PRESET_AND_MASK;
2253  unsigned int j;
2254 
2255  if ( _papi_hwi_presets[i].symbol ) { /* if the event is in the preset table */
2256  // since we are setting the whole structure to zero the strncpy calls below will
2257  // be leaving NULL terminates strings as long as they copy 1 less byte than the
2258  // buffer size of the field.
2259  memset( info, 0, sizeof ( PAPI_event_info_t ) );
2260 
2261  info->event_code = ( unsigned int ) EventCode;
2262  strncpy( info->symbol, _papi_hwi_presets[i].symbol,
2263  sizeof(info->symbol)-1);
2264 
2265  if ( _papi_hwi_presets[i].short_descr != NULL )
2266  strncpy( info->short_descr, _papi_hwi_presets[i].short_descr,
2267  sizeof ( info->short_descr )-1 );
2268 
2269  if ( _papi_hwi_presets[i].long_descr != NULL )
2270  strncpy( info->long_descr, _papi_hwi_presets[i].long_descr,
2271  sizeof ( info->long_descr )-1 );
2272 
2274  info->count = _papi_hwi_presets[i].count;
2275 
2277  info->derived, sizeof ( info->derived ) );
2278 
2279  if ( _papi_hwi_presets[i].postfix != NULL )
2280  strncpy( info->postfix, _papi_hwi_presets[i].postfix,
2281  sizeof ( info->postfix )-1 );
2282 
2283  for(j=0;j < info->count; j++) {
2284  info->code[j]=_papi_hwi_presets[i].code[j];
2285  strncpy(info->name[j], _papi_hwi_presets[i].name[j],
2286  sizeof(info->name[j])-1);
2287  }
2288 
2289  if ( _papi_hwi_presets[i].note != NULL ) {
2290  strncpy( info->note, _papi_hwi_presets[i].note,
2291  sizeof ( info->note )-1 );
2292  }
2293 
2294  return PAPI_OK;
2295  } else {
2296  return PAPI_ENOEVNT;
2297  }
2298 }
2299 
2300 
2301 /* _papi_hwi_get_user_event_info:
2302  Assumes EventCode contains a valid user event code.
2303  But defensive programming says check for NULL pointers.
2304  Returns a filled in PAPI_event_info_t structure containing
2305  descriptive strings and values for the specified preset event.
2306 */
2307 int
2309 {
2310  INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info);
2311 
2312  unsigned int i = EventCode & PAPI_UE_AND_MASK;
2313  unsigned int j;
2314 
2315  // if event code not in valid range, return error
2316  if (i >= PAPI_MAX_USER_EVENTS) {
2317  INTDBG("EXIT: Invalid event index: %d, max value is: %d\n", i, PAPI_MAX_USER_EVENTS - 1);
2318  return( PAPI_ENOEVNT );
2319  }
2320 
2321  if ( user_defined_events[i].symbol == NULL) { /* if the event is in the preset table */
2322  INTDBG("EXIT: Event symbol for this event is NULL\n");
2323  return PAPI_ENOEVNT;
2324  }
2325 
2326  /* set whole structure to 0 */
2327  memset( info, 0, sizeof ( PAPI_event_info_t ) );
2328 
2329  info->event_code = ( unsigned int ) EventCode;
2330  strncpy( info->symbol, user_defined_events[i].symbol,
2331  sizeof(info->symbol)-1);
2332 
2333  if ( user_defined_events[i].short_descr != NULL )
2334  strncpy( info->short_descr, user_defined_events[i].short_descr,
2335  sizeof(info->short_descr)-1);
2336 
2337  if ( user_defined_events[i].long_descr != NULL )
2338  strncpy( info->long_descr, user_defined_events[i].long_descr,
2339  sizeof(info->long_descr)-1);
2340 
2341 // info->event_type = user_defined_events[i].event_type;
2342  info->count = user_defined_events[i].count;
2343 
2344  _papi_hwi_derived_string( user_defined_events[i].derived_int,
2345  info->derived, sizeof(info->derived)-1);
2346 
2347  if ( user_defined_events[i].postfix != NULL )
2348  strncpy( info->postfix, user_defined_events[i].postfix,
2349  sizeof(info->postfix)-1);
2350 
2351  for(j=0;j < info->count; j++) {
2352  info->code[j]=user_defined_events[i].code[j];
2353  INTDBG("info->code[%d]: %#x\n", j, info->code[j]);
2354  strncpy(info->name[j], user_defined_events[i].name[j], sizeof(info->name[j])-1);
2355  }
2356 
2357  if ( user_defined_events[i].note != NULL ) {
2358  strncpy( info->note, user_defined_events[i].note, sizeof(info->note)-1);
2359  }
2360 
2361  INTDBG("EXIT: PAPI_OK: event_code: %#x, symbol: %s, short_desc: %s, long_desc: %s\n", info->event_code, info->symbol, info->short_descr, info->long_descr);
2362  return PAPI_OK;
2363 }
2364 
2365 
2366 /* Returns PAPI_OK if native EventCode found, or PAPI_ENOEVNT if not;
2367  Used to enumerate the entire array, e.g. for native_avail.c */
2368 int
2369 _papi_hwi_query_native_event( unsigned int EventCode )
2370 {
2371  INTDBG("ENTER: EventCode: %#x\n", EventCode);
2372  char name[PAPI_HUGE_STR_LEN]; /* probably overkill, */
2373  /* but should always be big enough */
2374  int cidx;
2375  int nevt_code;
2376 
2377  cidx = _papi_hwi_component_index( EventCode );
2378  if (cidx<0) {
2379  INTDBG("EXIT: PAPI_ENOCMP\n");
2380  return PAPI_ENOCMP;
2381  }
2382 
2383  // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
2384  _papi_hwi_set_papi_event_code(EventCode, 0);
2385 
2386  if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
2387  INTDBG("EXIT: nevt_code: %d\n", nevt_code);
2388  return nevt_code;
2389  }
2390  int ret = _papi_hwd[cidx]->ntv_code_to_name( (unsigned int)nevt_code, name, sizeof(name));
2391 
2392  INTDBG("EXIT: ret: %d\n", ret);
2393  return (ret);
2394 }
2395 
2396 /* Converts an ASCII name into a native event code usable by other routines
2397  Returns code = 0 and PAPI_OK if name not found.
2398  This allows for sparse native event arrays */
2399 int
2401 {
2402  INTDBG("ENTER: in: %s, out: %p\n", in, out);
2403 
2404  int retval = PAPI_ENOEVNT;
2405  char name[PAPI_HUGE_STR_LEN]; /* make sure it's big enough */
2406  unsigned int i;
2407  int cidx;
2408  char *full_event_name;
2409 
2410  if (in == NULL) {
2411  INTDBG("EXIT: PAPI_EINVAL\n");
2412  return PAPI_EINVAL;
2413  }
2414 
2415  full_event_name = strdup(in);
2416 
2418 
2419  // look in each component
2420  for(cidx=0; cidx < papi_num_components; cidx++) {
2421 
2422  if (_papi_hwd[cidx]->cmp_info.disabled) continue;
2423 
2424  // if this component does not support the pmu which defines this event, no need to call it
2425  if (is_supported_by_component(cidx, full_event_name) == 0) continue;
2426 
2427  INTDBG("cidx: %d, name: %s, event: %s\n", cidx, _papi_hwd[cidx]->cmp_info.name, in);
2428 
2429  // show that we do not have an event code yet (the component may create one and update this info)
2430  // this also clears any values left over from a previous call
2432 
2433 
2434  // if component has a ntv_name_to_code function, use it to get event code
2435  if (_papi_hwd[cidx]->ntv_name_to_code != NULL) {
2436  // try and get this events event code
2437  retval = _papi_hwd[cidx]->ntv_name_to_code( in, ( unsigned * ) out );
2438  if (retval==PAPI_OK) {
2439  *out = _papi_hwi_native_to_eventcode(cidx, *out, -1, in);
2440  free (full_event_name);
2441  INTDBG("EXIT: PAPI_OK event: %s code: %#x\n", in, *out);
2442  return PAPI_OK;
2443  }
2444  } else {
2445  // force the code through the work around
2446  retval = PAPI_ECMP;
2447  }
2448 
2449  /* If not implemented, work around */
2450  if ( retval==PAPI_ECMP) {
2451  i = 0;
2452  retval = _papi_hwd[cidx]->ntv_enum_events( &i, PAPI_ENUM_FIRST );
2453  if (retval != PAPI_OK) {
2454  free (full_event_name);
2455  INTDBG("EXIT: retval: %d\n", retval);
2456  return retval;
2457  }
2458 
2459 // _papi_hwi_lock( INTERNAL_LOCK );
2460 
2461  do {
2462  // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
2464  retval = _papi_hwd[cidx]->ntv_code_to_name(i, name, sizeof(name));
2465  /* printf("%#x\nname =|%s|\ninput=|%s|\n", i, name, in); */
2466  if ( retval == PAPI_OK && in != NULL) {
2467  if ( strcasecmp( name, in ) == 0 ) {
2468  *out = _papi_hwi_native_to_eventcode(cidx, i, -1, name);
2469  free (full_event_name);
2470  INTDBG("EXIT: PAPI_OK, event: %s, code: %#x\n", in, *out);
2471  return PAPI_OK;
2472  }
2473  retval = PAPI_ENOEVNT;
2474  } else {
2475  *out = 0;
2476  retval = PAPI_ENOEVNT;
2477  break;
2478  }
2479  } while ( ( _papi_hwd[cidx]->ntv_enum_events( &i, PAPI_ENUM_EVENTS ) == PAPI_OK ) );
2480 
2481 // _papi_hwi_unlock( INTERNAL_LOCK );
2482  }
2483  }
2484 
2485  free (full_event_name);
2486  INTDBG("EXIT: retval: %d\n", retval);
2487  return retval;
2488 }
2489 
2490 /* Returns event name based on native event code.
2491  Returns NULL if name not found */
2492 int
2493 _papi_hwi_native_code_to_name( unsigned int EventCode,
2494  char *hwi_name, int len )
2495 {
2496  INTDBG("ENTER: EventCode: %#x, hwi_name: %p, len: %d\n", EventCode, hwi_name, len);
2497  int cidx;
2498  int retval;
2499  int nevt_code;
2500 
2501  cidx = _papi_hwi_component_index( EventCode );
2502  if (cidx<0) return PAPI_ENOEVNT;
2503 
2504  if ( EventCode & PAPI_NATIVE_MASK ) {
2505  // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
2506  _papi_hwi_set_papi_event_code(EventCode, 0);
2507 
2508  if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
2509  INTDBG("EXIT: nevt_code: %d\n", nevt_code);
2510  return nevt_code;
2511  }
2512  if ( (retval = _papi_hwd[cidx]->ntv_code_to_name(
2513  (unsigned int)nevt_code,
2514  hwi_name, len) ) == PAPI_OK ) {
2515  retval = _papi_hwi_prefix_component_name( _papi_hwd[cidx]->cmp_info.short_name,
2516  hwi_name, hwi_name, len);
2517  INTDBG("EXIT: retval: %d\n", retval);
2518  return retval;
2519  }
2520  INTDBG("EXIT: retval: %d\n", retval);
2521  return (retval);
2522  }
2523  INTDBG("EXIT: PAPI_ENOEVNT\n");
2524  return PAPI_ENOEVNT;
2525 }
2526 
2527 
2528 
2529 /* The native event equivalent of PAPI_get_event_info */
2530 int
2531 _papi_hwi_get_native_event_info( unsigned int EventCode,
2532  PAPI_event_info_t *info )
2533 {
2534  INTDBG("ENTER: EventCode: %#x, info: %p\n", EventCode, info);
2535  int retval;
2536  int cidx;
2537  int nevt_code;
2538 
2539  cidx = _papi_hwi_component_index( EventCode );
2540  if (cidx<0) return PAPI_ENOCMP;
2541 
2542  if (_papi_hwd[cidx]->cmp_info.disabled) return PAPI_ENOCMP;
2543 
2544  if ( EventCode & PAPI_NATIVE_MASK ) {
2545  // save event code so components can get it with call to: _papi_hwi_get_papi_event_code()
2546  _papi_hwi_set_papi_event_code(EventCode, 0);
2547 
2548  /* clear the event info */
2549  memset( info, 0, sizeof ( PAPI_event_info_t ) );
2550  info->event_code = ( unsigned int ) EventCode;
2551 
2552  retval = _papi_hwd[cidx]->ntv_code_to_info(
2553  _papi_hwi_eventcode_to_native(EventCode), info);
2554 
2555  /* If component error, it's missing the ntv_code_to_info vector */
2556  /* so we'll have to fake it. */
2557  if ( retval == PAPI_ECMP ) {
2558 
2559 
2560  INTDBG("missing NTV_CODE_TO_INFO, faking\n");
2561  /* Fill in the info structure */
2562 
2563  if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) < 0) {
2564  INTDBG("EXIT: nevt_code: %d\n", nevt_code);
2565  return nevt_code;
2566  }
2567  if ( (retval = _papi_hwd[cidx]->ntv_code_to_name(
2568  (unsigned int)nevt_code,
2569  info->symbol,
2570  sizeof(info->symbol)) ) == PAPI_OK ) {
2571 
2572  } else {
2573  INTDBG("EXIT: retval: %d\n", retval);
2574  return retval;
2575  }
2576 
2577  if ((nevt_code = _papi_hwi_eventcode_to_native(EventCode)) <0) {
2578  INTDBG("EXIT: nevt_code: %d\n", nevt_code);
2579  return nevt_code;
2580  }
2581  retval = _papi_hwd[cidx]->ntv_code_to_descr(
2582  (unsigned int)nevt_code,
2583  info->long_descr,
2584  sizeof ( info->long_descr));
2585  if (retval!=PAPI_OK) {
2586  INTDBG("Failed ntv_code_to_descr()\n");
2587  }
2588 
2589  }
2591  _papi_hwd[cidx]->cmp_info.short_name,
2592  info->symbol,
2593  info->symbol,
2594  sizeof(info->symbol) );
2595 
2596  INTDBG("EXIT: retval: %d\n", retval);
2597  return retval;
2598  }
2599 
2600  INTDBG("EXIT: PAPI_ENOEVNT\n");
2601  return PAPI_ENOEVNT;
2602 }
2603 
2606 {
2607  const DynamicArray_t *map = &_papi_hwi_system_info.global_eventset_map;
2608  EventSetInfo_t *set;
2609 
2610  if ( ( eventset < 0 ) || ( eventset > map->totalSlots ) )
2611  return ( NULL );
2612 
2613  set = map->dataSlotArray[eventset];
2614 #ifdef DEBUG
2615  if ( ( ISLEVEL( DEBUG_THREADS ) ) && ( _papi_hwi_thread_id_fn ) &&
2616  ( set->master->tid != _papi_hwi_thread_id_fn( ) ) )
2617  return ( NULL );
2618 #endif
2619 
2620  return ( set );
2621 }
2622 
2623 int
2625 {
2626  /* Are we multiplexing at all */
2627  if ( ( ESI->state & PAPI_MULTIPLEXING ) == 0 ) {
2628  return 0;
2629  }
2630 
2631  /* Does the component support kernel multiplexing */
2632  if ( _papi_hwd[ESI->CmpIdx]->cmp_info.kernel_multiplex ) {
2633  /* Have we forced software multiplexing */
2634  if ( ESI->multiplex.flags == PAPI_MULTIPLEX_FORCE_SW ) {
2635  return 1;
2636  }
2637  /* Nope, using hardware multiplexing */
2638  return 0;
2639  }
2640 
2641  /* We are multiplexing but the component does not support hardware */
2642 
2643  return 1;
2644 
2645 }
2646 
2647 hwd_context_t *
2648 _papi_hwi_get_context( EventSetInfo_t * ESI, int *is_dirty )
2649 {
2650  INTDBG("Entry: ESI: %p, is_dirty: %p\n", ESI, is_dirty);
2651  int dirty_ctx;
2652  hwd_context_t *ctx=NULL;
2653 
2654  /* assume for now the control state is clean (last updated by this ESI) */
2655  dirty_ctx = 0;
2656 
2657  /* get a context pointer based on if we are counting for a thread or for a cpu */
2658  if (ESI->state & PAPI_CPU_ATTACHED) {
2659  /* use cpu context */
2660  ctx = ESI->CpuInfo->context[ESI->CmpIdx];
2661 
2662  /* if the user wants to know if the control state was last set by the same event set, tell him */
2663  if (is_dirty != NULL) {
2664  if (ESI->CpuInfo->from_esi != ESI) {
2665  dirty_ctx = 1;
2666  }
2667  *is_dirty = dirty_ctx;
2668  }
2669  ESI->CpuInfo->from_esi = ESI;
2670 
2671  } else {
2672 
2673  /* use thread context */
2674  ctx = ESI->master->context[ESI->CmpIdx];
2675 
2676  /* if the user wants to know if the control state was last set by the same event set, tell him */
2677  if (is_dirty != NULL) {
2678  if (ESI->master->from_esi != ESI) {
2679  dirty_ctx = 1;
2680  }
2681  *is_dirty = dirty_ctx;
2682  }
2683  ESI->master->from_esi = ESI;
2684 
2685  }
2686  return( ctx );
2687 }
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
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
#define PAPI_UE_AND_MASK
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:54
#define PAPI_NULL
Definition: papi.h:290
static int top
Definition: papi_preset.c:794
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
for(i=0;i<=max_y;i++)
Definition: iozone.c:11615
#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()
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:56
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
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
int _papi_hwi_get_user_event_info(int EventCode, PAPI_event_info_t *info)
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)
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)
#define PAPI_MAX_USER_EVENTS
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
static char * stack[STACK_MAX]
Definition: papi_preset.c:792
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 user_defined_events_count
Definition: papi_internal.c:59
#define DERIVED_INFIX
Definition: papi_internal.h:76
hwi_presets_t user_defined_events[PAPI_MAX_USER_EVENTS]
Definition: papi_internal.c:58
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:53
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:57
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:55
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:86
#define papi_realloc(a, b)
Definition: papi_memory.h:36
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_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)
#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:52
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:114
#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