PAPI  5.6.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pe_libpfm4_events.c File Reference
Include dependency graph for pe_libpfm4_events.c:

Go to the source code of this file.

Macros

#define NATIVE_EVENT_CHUNK   1024
 

Functions

static int find_existing_event (const char *name, struct native_event_table_t *event_table)
 
static int pmu_is_present_and_right_type (pfm_pmu_info_t *pinfo, int type)
 
static struct native_event_tallocate_native_event (const char *name, int libpfm4_index, int cidx, struct native_event_table_t *event_table)
 
static int get_first_event_next_pmu (int pmu_idx, int pmu_type)
 
int _pe_libpfm4_ntv_name_to_code (const char *name, unsigned int *event_code, int cidx, struct native_event_table_t *event_table)
 
int _pe_libpfm4_ntv_code_to_name (unsigned int EventCode, char *ntv_name, int len, struct native_event_table_t *event_table)
 
int _pe_libpfm4_ntv_code_to_descr (unsigned int EventCode, char *ntv_descr, int len, struct native_event_table_t *event_table)
 
int _pe_libpfm4_ntv_code_to_info (unsigned int EventCode, PAPI_event_info_t *info, struct native_event_table_t *event_table)
 
int _pe_libpfm4_ntv_enum_events (unsigned int *PapiEventCode, int modifier, int cidx, struct native_event_table_t *event_table)
 
int _pe_libpfm4_shutdown (papi_vector_t *my_vector, struct native_event_table_t *event_table)
 
int _pe_libpfm4_init (papi_vector_t *component, int cidx, struct native_event_table_t *event_table, int pmu_type)
 
int _peu_libpfm4_init (papi_vector_t *my_vector, int cidx, struct native_event_table_t *event_table, int pmu_type)
 

Variables

static int attr_idx
 

Macro Definition Documentation

#define NATIVE_EVENT_CHUNK   1024

Definition at line 29 of file pe_libpfm4_events.c.

Function Documentation

int _pe_libpfm4_init ( papi_vector_t component,
int  cidx,
struct native_event_table_t event_table,
int  pmu_type 
)

Definition at line 1123 of file pe_libpfm4_events.c.

1125  {
1126 
1127  int detected_pmus=0, found_default=0;
1128  int i;
1129  int j=0;
1130  unsigned int ncnt;
1131 
1132  pfm_err_t retval = PFM_SUCCESS;
1133  pfm_pmu_info_t pinfo;
1134 
1135  /* allocate the native event structure */
1136  event_table->num_native_events=0;
1137  event_table->pmu_type=pmu_type;
1138 
1139  event_table->native_events=calloc(NATIVE_EVENT_CHUNK,
1140  sizeof(struct native_event_t));
1141  if (event_table->native_events==NULL) {
1142  strncpy(component->cmp_info.disabled_reason,
1143  "calloc NATIVE_EVENT_CHUNK failed",PAPI_MAX_STR_LEN);
1144  return PAPI_ENOMEM;
1145  }
1146 
1148 
1149  /* Count number of present PMUs */
1150  detected_pmus=0;
1151  ncnt=0;
1152 
1153  /* init default pmu */
1154  /* need to init pinfo or pfmlib might complain */
1155  memset(&(event_table->default_pmu), 0, sizeof(pfm_pmu_info_t));
1156  event_table->default_pmu.size = sizeof(pfm_pmu_info_t);
1157  retval=pfm_get_pmu_info(0, &(event_table->default_pmu));
1158 
1159  SUBDBG("Detected pmus:\n");
1160  i=0;
1161  while(1) {
1162  memset(&pinfo,0,sizeof(pfm_pmu_info_t));
1163  pinfo.size = sizeof(pfm_pmu_info_t);
1164  retval=pfm_get_pmu_info(i, &pinfo);
1165 
1166  /* We're done if we hit an invalid PMU entry */
1167  /* We can't check against PFM_PMU_MAX as that might not */
1168  /* match if libpfm4 is dynamically linked */
1169 
1170  if (retval==PFM_ERR_INVAL) {
1171  break;
1172  }
1173 
1174  if ((retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1175  (pmu_is_present_and_right_type(&pinfo,pmu_type))) {
1176 
1177  SUBDBG("\t%d %s %s %d\n",i,
1178  pinfo.name,pinfo.desc,pinfo.type);
1179 
1180  detected_pmus++;
1181  ncnt+=pinfo.nevents;
1182 
1183  if (j < PAPI_PMU_MAX) {
1184  component->cmp_info.pmu_names[j++] =
1185  strdup(pinfo.name);
1186  }
1187 
1188  if (pmu_type & PMU_TYPE_CORE) {
1189 
1190  /* Hack to have "default core" PMU */
1191  if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
1192  strcmp(pinfo.name,"ix86arch")) {
1193 
1194  SUBDBG("\t %s is default\n",pinfo.name);
1195  memcpy(&(event_table->default_pmu),
1196  &pinfo,sizeof(pfm_pmu_info_t));
1197  found_default++;
1198  }
1199  }
1200 
1201  if (pmu_type==PMU_TYPE_UNCORE) {
1202  /* To avoid confusion, no "default" CPU for uncore */
1203  found_default=1;
1204  }
1205  }
1206  i++;
1207  }
1208  SUBDBG("%d native events detected on %d pmus\n",ncnt,detected_pmus);
1209 
1210  if (detected_pmus==0) {
1211  SUBDBG("Could not find any PMUs\n");
1212  return PAPI_ENOSUPP;
1213  }
1214 
1215  if (!found_default) {
1216  strncpy(component->cmp_info.disabled_reason,
1217  "could not find default PMU",PAPI_MAX_STR_LEN);
1218  return PAPI_ECMP;
1219  }
1220 
1221  if (found_default>1) {
1222  strncpy(component->cmp_info.disabled_reason,
1223  "found more than one default PMU",PAPI_MAX_STR_LEN);
1224  return PAPI_ECOUNT;
1225  }
1226 
1227  component->cmp_info.num_native_events = ncnt;
1228 
1229  component->cmp_info.num_cntrs = event_table->default_pmu.num_cntrs+
1230  event_table->default_pmu.num_fixed_cntrs;
1231 
1232  SUBDBG( "num_counters: %d\n", component->cmp_info.num_cntrs );
1233 
1234  /* Setup presets, only if Component 0 and default core PMU */
1235  if ((cidx==0) && (found_default)) {
1236  retval = _papi_load_preset_table( (char *)event_table->default_pmu.name,
1237  event_table->default_pmu.pmu, cidx );
1238  if ( retval!=PAPI_OK ) {
1239  strncpy(component->cmp_info.disabled_reason,"_papi_load_preset_table failed",PAPI_MAX_STR_LEN);
1240  return PAPI_ENOEVNT;
1241  }
1242  }
1243 
1244  return PAPI_OK;
1245 }
#define PAPI_ENOEVNT
Definition: papi.h:260
struct native_event_t * native_events
#define PAPI_ENOSUPP
Definition: papi.h:271
#define NATIVE_EVENT_CHUNK
return PAPI_OK
Definition: linux-nvml.c:497
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
static int cidx
char disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:636
int i
Definition: fileop.c:140
#define PAPI_PMU_MAX
Definition: papi.h:469
char * pmu_names[PAPI_PMU_MAX]
Definition: papi.h:650
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define PAPI_ECMP
Definition: papi.h:256
#define PMU_TYPE_CORE
int _papi_load_preset_table(char *pmu_str, int pmu_type, int cidx)
Definition: papi_preset.c:771
#define PAPI_ENOMEM
Definition: papi.h:254
static int pmu_is_present_and_right_type(pfm_pmu_info_t *pinfo, int type)
#define PMU_TYPE_UNCORE
pfm_pmu_info_t default_pmu
#define PAPI_MAX_STR_LEN
Definition: papi.h:465
long j
Definition: iozone.c:19135
ssize_t retval
Definition: libasync.c:338
#define PAPI_ECOUNT
Definition: papi.h:276

Here is the call graph for this function:

Here is the caller graph for this function:

int _pe_libpfm4_ntv_code_to_descr ( unsigned int  EventCode,
char *  ntv_descr,
int  len,
struct native_event_table_t event_table 
)

Definition at line 702 of file pe_libpfm4_events.c.

705 {
706  SUBDBG("ENTER: EventCode: %#x, ntv_descr: %p, len: %d: event_table: %p\n", EventCode, ntv_descr, len, event_table);
707 
708  int eidx;
709  int papi_event_code;
710  char *mdesc;
711  char *edesc;
712 
713  // get the attribute index for this papi event
714  papi_event_code = _papi_hwi_get_papi_event_code();
715 
716  // a papi event code less than 0 is invalid, return error
717  if (papi_event_code <= 0) {
718  SUBDBG("EXIT: PAPI_ENOEVNT\n");
719  return PAPI_ENOEVNT;
720  }
721 
722  // find our native event table for this papi event code (search list backwards because it improves chances of finding it quickly)
723  for (eidx=event_table->num_native_events-1 ; eidx>=0 ; eidx--) {
724  SUBDBG("native_event[%d]: papi_event_code: %#x, libpfm4_idx: %#x\n", eidx, event_table->native_events[eidx].papi_event_code, event_table->native_events[eidx].libpfm4_idx);
725  if ((papi_event_code == event_table->native_events[eidx].papi_event_code) && (EventCode == ((unsigned)event_table->native_events[eidx].libpfm4_idx))) {
726  break;
727  }
728  }
729 
730  // if we did not find a match, return an error
731  if (eidx < 0) {
732  // If we did not find a match in our native event table, then the code passed in has not been
733  // allocated yet It should not be possible to get to this code. The user has to call the papi
734  // code_to_name api with a papi event code for a native event. But the only way to get one of
735  // those is to call either name_to_code or enum_cmp_events first. When one of these calls is
736  // done we allocate the event so it should always be there.
737 
738  SUBDBG("EXIT: PAPI_ENOEVNT\n");
739  return PAPI_ENOEVNT;
740  }
741 
742  edesc = event_table->native_events[eidx].event_description;
743 
744  // if it will not fit, return error
745  if (strlen (edesc) >= (unsigned)len) {
746  SUBDBG("EXIT: event name %s will not fit in buffer provided\n", edesc);
747  return PAPI_EBUF;
748  }
749  strcpy (ntv_descr, edesc);
750 
751  // if this event had masks, also add their descriptions
752  mdesc = event_table->native_events[eidx].mask_description;
753  if ((mdesc != NULL) && (strlen(mdesc) > 0)) {
754  if ((strlen(edesc) + 8 + strlen(mdesc)) >= (unsigned)len) {
755  SUBDBG("EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (unsigned)(strlen(edesc) + 8 + strlen(mdesc)), (unsigned)len);
756  return PAPI_EBUF;
757  }
758  strcat (ntv_descr, ", masks:");
759  strcat (ntv_descr, mdesc);
760  }
761 
762  SUBDBG("EXIT: event description: %s\n", ntv_descr);
763  return PAPI_OK;
764 }
#define PAPI_ENOEVNT
Definition: papi.h:260
static unsigned int papi_event_code
unsigned int _papi_hwi_get_papi_event_code()
struct native_event_t * native_events
return PAPI_OK
Definition: linux-nvml.c:497
#define PAPI_EBUF
Definition: papi.h:273
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
strcat(command, mountname)
strcpy(filename, default_filename)

Here is the call graph for this function:

Here is the caller graph for this function:

int _pe_libpfm4_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info,
struct native_event_table_t event_table 
)

Definition at line 768 of file pe_libpfm4_events.c.

771 {
772  SUBDBG("ENTER: EventCode: %#x, info: %p, event_table: %p\n", EventCode, info, event_table);
773 
774  int ret;
775 
776  // get the event name first
777  if ((ret = _pe_libpfm4_ntv_code_to_name(EventCode, info->symbol, sizeof(info->symbol), event_table)) != PAPI_OK) {
778  SUBDBG("EXIT: _pe_libpfm4_ntv_code_to_name returned: %d\n", ret);
779  return PAPI_ENOEVNT;
780  }
781 
782  if ((ret = _pe_libpfm4_ntv_code_to_descr(EventCode, info->long_descr, sizeof(info->long_descr), event_table)) != PAPI_OK) {
783  SUBDBG("EXIT: _pe_libpfm4_ntv_code_to_descr returned: %d\n", ret);
784  return PAPI_ENOEVNT;
785  }
786 
787  SUBDBG("EXIT: EventCode: %#x, name: %s, desc: %s\n", EventCode, info->symbol, info->long_descr);
788  return PAPI_OK;
789 }
#define PAPI_ENOEVNT
Definition: papi.h:260
char long_descr[PAPI_HUGE_STR_LEN]
Definition: papi.h:969
char symbol[PAPI_HUGE_STR_LEN]
Definition: papi.h:966
return PAPI_OK
Definition: linux-nvml.c:497
long long ret
Definition: iozone.c:1346
int _pe_libpfm4_ntv_code_to_name(unsigned int EventCode, char *ntv_name, int len, struct native_event_table_t *event_table)
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
int _pe_libpfm4_ntv_code_to_descr(unsigned int EventCode, char *ntv_descr, int len, struct native_event_table_t *event_table)

Here is the call graph for this function:

Here is the caller graph for this function:

int _pe_libpfm4_ntv_code_to_name ( unsigned int  EventCode,
char *  ntv_name,
int  len,
struct native_event_table_t event_table 
)

Definition at line 609 of file pe_libpfm4_events.c.

612 {
613  SUBDBG("ENTER: EventCode: %#x, ntv_name: %p, len: %d, event_table: %p\n", EventCode, ntv_name, len, event_table);
614 
615  int eidx;
616  int papi_event_code;
617 
618  // get the attribute index for this papi event
619  papi_event_code = _papi_hwi_get_papi_event_code();
620 
621  // a papi event code less than 0 is invalid, return error
622  if (papi_event_code <= 0) {
623  SUBDBG("EXIT: PAPI_ENOEVNT\n");
624  return PAPI_ENOEVNT;
625  }
626 
627  // find our native event table for this papi event code (search list backwards because it improves chances of finding it quickly)
628  for (eidx=event_table->num_native_events-1 ; eidx>=0 ; eidx--) {
629  if ((papi_event_code == event_table->native_events[eidx].papi_event_code) && (EventCode == ((unsigned)event_table->native_events[eidx].libpfm4_idx))) {
630  SUBDBG("Found native_event[%d]: papi_event_code: %#x, libpfm4_idx: %#x\n", eidx, event_table->native_events[eidx].papi_event_code, event_table->native_events[eidx].libpfm4_idx);
631  break;
632  }
633  }
634 
635  // if we did not find a match, return an error
636  if (eidx < 0) {
637  // If we did not find a match in our native event table, then the code passed in has not been
638  // allocated yet It should not be possible to get to this code. The user has to call the papi
639  // code_to_name api with a papi event code for a native event. But the only way to get one of
640  // those is to call either name_to_code or enum_cmp_events first. When one of these calls is
641  // done we allocate the event so it should always be there.
642 
643  SUBDBG("EXIT: PAPI_ENOEVNT\n");
644  return PAPI_ENOEVNT;
645  }
646 
647  // if this event is defined by the default pmu, then use only the event name
648  // if it is not defined by the default pmu, then use both the pmu name and event name
649  char *ename;
650  if ((event_table->default_pmu.name) && (strcmp(event_table->default_pmu.name, event_table->native_events[eidx].pmu) == 0)) {
651  ename = event_table->native_events[eidx].base_name;
652  } else {
653  ename = event_table->native_events[eidx].pmu_plus_name;
654  }
655 
656  // if it will not fit, return error
657  if (strlen (ename) >= (unsigned)len) {
658  SUBDBG("EXIT: event name %s will not fit in buffer provided\n", ename);
659  return PAPI_EBUF;
660  }
661  strcpy (ntv_name, ename);
662 
663  // if this event had masks, also add their names
664  char *mname = event_table->native_events[eidx].mask_string;
665  if ((mname != NULL) && (strlen(mname) > 0)) {
666  if ((strlen(ename) + 8 + strlen(mname)) >= (unsigned)len) {
667  SUBDBG("EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (unsigned)(strlen(ename) + 8 + strlen(mname)), (unsigned)len);
668  return PAPI_EBUF;
669  }
670  strcat (ntv_name, ":");
671  strcat (ntv_name, mname);
672  }
673 
674  SUBDBG("EXIT: event name: %s\n", ntv_name);
675  return PAPI_OK;
676 }
#define PAPI_ENOEVNT
Definition: papi.h:260
static unsigned int papi_event_code
unsigned int _papi_hwi_get_papi_event_code()
struct native_event_t * native_events
return PAPI_OK
Definition: linux-nvml.c:497
#define PAPI_EBUF
Definition: papi.h:273
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
strcat(command, mountname)
strcpy(filename, default_filename)
pfm_pmu_info_t default_pmu

Here is the call graph for this function:

Here is the caller graph for this function:

int _pe_libpfm4_ntv_enum_events ( unsigned int PapiEventCode,
int  modifier,
int  cidx,
struct native_event_table_t event_table 
)

Definition at line 809 of file pe_libpfm4_events.c.

811  {
812 
813  SUBDBG("ENTER: PapiEventCode: %p, *PapiEventCode: %#x, modifier: %d, event_table: %p\n", PapiEventCode, *PapiEventCode, modifier, event_table);
814 
815  int code,ret, pnum;
816  int max_umasks;
817  char event_string[BUFSIZ];
818  pfm_pmu_info_t pinfo;
819  pfm_event_info_t einfo;
820  struct native_event_t *our_event;
821 
822  /* return first event if so specified */
823  if ( modifier == PAPI_ENUM_FIRST ) {
824  attr_idx = 0; // set so if they want attribute information, it will start with the first attribute
825  code=get_first_event_next_pmu(-1, event_table->pmu_type);
826  if (code < 0 ) {
827  SUBDBG("EXIT: Invalid component first event code: %d\n", code);
828  return code;
829  }
830 
831  // get the event information from libpfm4 (must zero structure)
832  memset( &einfo, 0, sizeof( pfm_event_info_t ));
833  einfo.size = sizeof(pfm_event_info_t);
834  if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
835  SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
836  return PAPI_ENOIMPL;
837  }
838 
839  // get the pmu information from libpfm4 (must zero structure)
840  memset( &pinfo, 0, sizeof(pfm_pmu_info_t) );
841  pinfo.size = sizeof(pfm_pmu_info_t);
842  ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
843  if (ret!=PFM_SUCCESS) {
844  SUBDBG("EXIT: pfm_get_pmu_info returned: %d\n", ret);
845  return ret;
846  }
847 
848  // build full event name
849  sprintf (event_string, "%s::%s", pinfo.name, einfo.name);
850  SUBDBG("code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
851 
852  // go allocate this event, need to create tables used by the get event info call that will probably follow
853  if ((our_event = allocate_native_event(event_string, code, cidx, event_table)) == NULL) {
854  // allocate may have created the event table but returned NULL to tell the caller the event string was invalid (attempt to encode it failed).
855  // if the caller wants to use this event to count something, it will report an error
856  // but if the caller is just interested in listing the event, then we need an event table with an event name and libpfm4 index
857  int evt_idx;
858  if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
859  SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
860  return PAPI_ENOEVNT;
861  }
862 
863  // give back the new event code
864  *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
865  SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
866  return PAPI_OK;
867  }
868 
869  *PapiEventCode = our_event->libpfm4_idx;
870 
871  SUBDBG("EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
872  return PAPI_OK;
873  }
874 
875  /* Handle looking for the next event */
876  if ( modifier == PAPI_ENUM_EVENTS ) {
877  attr_idx = 0; // set so if they want attribute information, it will start with the first attribute
878 
879  // get the next event code from libpfm4, if there are no more in this pmu find first event in next pmu
880  if ((code = pfm_get_event_next(*PapiEventCode)) < 0) {
881 
882  // get this events information from libpfm4, we need the pmu number of the last event we processed (table must be cleared)
883  memset( &einfo, 0, sizeof( pfm_event_info_t ));
884  einfo.size = sizeof(pfm_event_info_t);
885  if ((ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
886  SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
887  return PAPI_ENOIMPL;
888  }
889  SUBDBG("*PapiEventCode: %#x, event: %s\n", *PapiEventCode, einfo.name);
890 
891  // get the pmu number of the last event
892  pnum = einfo.pmu;
893 
894  SUBDBG("pnum: %d\n", pnum);
895  code=get_first_event_next_pmu(pnum, event_table->pmu_type);
896  if (code < 0) {
897  SUBDBG("EXIT: No more PMUs to list, returning: %d\n", code);
898  return code;
899  }
900  }
901 
902 
903  // get the event information from libpfm4 (must zero structure)
904  memset( &einfo, 0, sizeof( pfm_event_info_t ));
905  einfo.size = sizeof(pfm_event_info_t);
906  if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
907  SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
908  return PAPI_ENOIMPL;
909  }
910 
911  // get the pmu information from libpfm4 (must zero structure)
912  memset( &pinfo, 0, sizeof(pfm_pmu_info_t) );
913  pinfo.size = sizeof(pfm_pmu_info_t);
914  ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
915  if (ret!=PFM_SUCCESS) {
916  SUBDBG("EXIT: pfm_get_pmu_info returned: %d\n", ret);
917  return ret;
918  }
919 
920  // build full event name
921  sprintf (event_string, "%s::%s", pinfo.name, einfo.name);
922  SUBDBG("code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
923 
924  // go allocate this event, need to create tables used by the get event info call that will follow
925  if ((our_event = allocate_native_event(event_string, code, cidx, event_table)) == NULL) {
926  // allocate may have created the event table but returned NULL to tell the caller the event string was invalid (attempt to encode it failed).
927  // if the caller wants to use this event to count something, it will report an error
928  // but if the caller is just interested in listing the event, then we need an event table with an event name and libpfm4 index
929  int evt_idx;
930  if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
931  SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
932  return PAPI_ENOEVNT;
933  }
934 
935  // give back the new event code
936  *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
937  SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
938  return PAPI_OK;
939  }
940 
941  // give back the new event code
942  *PapiEventCode = our_event->libpfm4_idx;
943 
944  SUBDBG("EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
945  return PAPI_OK;
946  }
947 
948  /* We don't handle PAPI_NTV_ENUM_UMASK_COMBOS */
949  if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) {
950  SUBDBG("EXIT: do not support umask combos yet\n");
951  return PAPI_ENOIMPL;
952  }
953 
954  /* Enumerate PAPI_NTV_ENUM_UMASKS (umasks on an event) */
955  if ( modifier == PAPI_NTV_ENUM_UMASKS ) {
956  // get this events information from libpfm4, we need the number of masks this event knows about (table must be cleared)
957  memset( &einfo, 0, sizeof( pfm_event_info_t ));
958  einfo.size = sizeof(pfm_event_info_t);
959  if ((ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
960  SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
961  return PAPI_ENOIMPL;
962  }
963 // SUBDBG("*PapiEventCode: %#x, einfo.name: %s, einfo.code: %#x, einfo.nattrs: %d\n", *PapiEventCode, einfo.name, einfo.code, einfo.nattrs);
964 
965  // set max number of masks
966  max_umasks = einfo.nattrs;
967 
968  // if we reached last attribute, return error to show we are done with this events masks
969  if (attr_idx == max_umasks) {
970  SUBDBG("EXIT: already processed all umasks: attr_idx: %d\n", attr_idx);
971  return PAPI_ENOEVNT;
972  }
973 
974  // find the event table for this event, we need the pmu name and event name without any masks
976  if (ntv_idx < 0) {
977  SUBDBG("EXIT: _papi_hwi_get_ntv_idx returned: %d\n", ntv_idx);
978  return ntv_idx;
979  }
980  char *ename = event_table->native_events[ntv_idx].pmu_plus_name;
981  if ((ename == NULL) || (strlen(ename) >= sizeof(event_string))) {
982  SUBDBG("EXIT: Event name will not fit into buffer\n");
983  return PAPI_EBUF;
984  }
985  strcpy (event_string, ename);
986  SUBDBG("event_string: %s\n", event_string);
987 
988  // go get the attribute information for this event
989  // libpfm4 likes the table cleared
990  pfm_event_attr_info_t ainfo;
991  memset (&ainfo, 0, sizeof(pfm_event_attr_info_t));
992  ainfo.size = sizeof(pfm_event_attr_info_t);
993  ret = pfm_get_event_attr_info(*PapiEventCode, attr_idx, PFM_OS_PERF_EVENT_EXT, &ainfo);
994  if (ret != PFM_SUCCESS) {
995  SUBDBG("EXIT: Attribute info not found, EventCode: %#x, attr_idx: %d, ret: %d\n", *PapiEventCode, attr_idx, _papi_libpfm4_error(ret));
996  return _papi_libpfm4_error(ret);
997  }
998  SUBDBG("*PapiEventCode: %#x, attr_idx: %d, type: %d, name: %s, description: %s\n", *PapiEventCode, attr_idx, ainfo.type, ainfo.name, ainfo.desc);
999 
1000  if (strlen(event_string) + strlen(ainfo.name) + 35 > sizeof(event_string)) {
1001  SUBDBG("EXIT: Event name and mask will not fit into buffer\n");
1002  return PAPI_EBUF;
1003  }
1004 
1005  strcat (event_string, ":");
1006  strcat (event_string, ainfo.name);
1007  switch (ainfo.type) {
1008  case PFM_ATTR_UMASK:
1009  break;
1010  case PFM_ATTR_MOD_BOOL:
1011  case PFM_ATTR_MOD_INTEGER:
1012  // a few attributes require a non-zero value to encode correctly (most would accept zero here)
1013  strcat(event_string,"=0");
1014  break;
1015  default:
1016  SUBDBG("EXIT: Unsupported attribute type: %d", ainfo.type);
1017  return PAPI_EATTR;
1018  }
1019 
1020  // go allocate this event, need to create tables used by the get event info call that will follow
1021  if ((our_event = allocate_native_event(event_string, *PapiEventCode, cidx, event_table)) == NULL) {
1022  // allocate may have created the event table but returned NULL to tell the caller the event string was invalid.
1023  // if the caller wants to use this event to count something, it must report the error
1024  // but if the caller is just interested in listing the event (like this code), then find the table that was created and return its libpfm4 index
1025  int evt_idx;
1026  if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
1027  SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
1028  return PAPI_ENOEVNT;
1029  }
1030  // bump so next time we will use next attribute
1031  attr_idx++;
1032  // give back the new event code
1033  *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
1034  SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
1035  return PAPI_OK;
1036  }
1037 
1038  // bump so next time we will use next attribute
1039  attr_idx++;
1040 
1041  // give back the new event code
1042  *PapiEventCode = our_event->libpfm4_idx;
1043 
1044  SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
1045  return PAPI_OK;
1046  }
1047 
1048  /* Enumerate PAPI_NTV_ENUM_GROUPS (groups on an event) */
1049  if ( modifier == PAPI_NTV_ENUM_GROUPS ) {
1050  SUBDBG("EXIT: do not support enumerating groups in this component\n");
1051  return PAPI_ENOIMPL;
1052  }
1053 
1054  /* An unknown enumeration method was indicated */
1055 
1056  SUBDBG("EXIT: Invalid modifier argument provided\n");
1057  return PAPI_ENOIMPL;
1058 }
#define PAPI_ENOEVNT
Definition: papi.h:260
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
static int get_first_event_next_pmu(int pmu_idx, int pmu_type)
int _papi_hwi_get_ntv_idx(unsigned int papi_evt_code)
unsigned int _papi_hwi_get_papi_event_code()
struct native_event_t * native_events
return PAPI_OK
Definition: linux-nvml.c:497
static int find_existing_event(const char *name, struct native_event_table_t *event_table)
#define PAPI_EBUF
Definition: papi.h:273
int _papi_libpfm4_error(int pfm_error)
static int attr_idx
long long ret
Definition: iozone.c:1346
static int cidx
#define PAPI_EATTR
Definition: papi.h:275
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
strcat(command, mountname)
#define PAPI_ENOIMPL
Definition: papi.h:272
static struct native_event_t * allocate_native_event(const char *name, int libpfm4_index, int cidx, struct native_event_table_t *event_table)
strcpy(filename, default_filename)

Here is the call graph for this function:

Here is the caller graph for this function:

int _pe_libpfm4_ntv_name_to_code ( const char *  name,
unsigned int event_code,
int  cidx,
struct native_event_table_t event_table 
)

Definition at line 559 of file pe_libpfm4_events.c.

562 {
563  SUBDBG( "ENTER: name: %s, event_code: %p, *event_code: %#x, event_table: %p\n", name, event_code, *event_code, event_table);
564 
565  struct native_event_t *our_event;
566  int event_num;
567 
568  // if we already know this event name, just return its native code
569  event_num=find_existing_event(name, event_table);
570  if (event_num >= 0) {
571  *event_code=event_table->native_events[event_num].libpfm4_idx;
572  // the following call needs to happen to prevent the internal layer from creating a new papi native event table
573  _papi_hwi_set_papi_event_code(event_table->native_events[event_num].papi_event_code, 1);
574  SUBDBG("EXIT: Found papi_event_code: %#x, libpfm4_idx: %#x\n", event_table->native_events[event_num].papi_event_code, event_table->native_events[event_num].libpfm4_idx);
575  return PAPI_OK;
576  }
577 
578  // Try to allocate this event to see if it is known by libpfm4, if allocate fails tell the caller it is not valid
579  our_event=allocate_native_event(name, -1, cidx, event_table);
580  if (our_event==NULL) {
581  SUBDBG("EXIT: Allocating event: '%s' failed\n", name);
582  return PAPI_ENOEVNT;
583  }
584 
585  *event_code = our_event->libpfm4_idx;
586  SUBDBG("EXIT: Found code: %#x\n",*event_code);
587  return PAPI_OK;
588 }
#define PAPI_ENOEVNT
Definition: papi.h:260
struct native_event_t * native_events
return PAPI_OK
Definition: linux-nvml.c:497
static int find_existing_event(const char *name, struct native_event_table_t *event_table)
static int cidx
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
static struct native_event_t * allocate_native_event(const char *name, int libpfm4_index, int cidx, struct native_event_table_t *event_table)
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
char * name
Definition: iozone.c:23648

Here is the call graph for this function:

Here is the caller graph for this function:

int _pe_libpfm4_shutdown ( papi_vector_t my_vector,
struct native_event_table_t event_table 
)

Definition at line 1072 of file pe_libpfm4_events.c.

1073  {
1074  SUBDBG("ENTER: event_table: %p\n", event_table);
1075 
1076  int i;
1077 
1078  for (i=0 ; i<PAPI_PMU_MAX ; i++) {
1079  if (my_vector->cmp_info.pmu_names[i] != NULL) {
1080  free (my_vector->cmp_info.pmu_names[i]);
1081  }
1082  }
1083 
1084  /* clean out and free the native events structure */
1086 
1087  /* free memory allocated with strdup or malloc */
1088  for( i=0; i<event_table->num_native_events; i++) {
1089  free(event_table->native_events[i].base_name);
1090  free(event_table->native_events[i].pmu_plus_name);
1091  free(event_table->native_events[i].pmu);
1092  free(event_table->native_events[i].allocated_name);
1093  free(event_table->native_events[i].mask_string);
1094  free(event_table->native_events[i].event_description);
1095  if (event_table->native_events[i].mask_description != NULL) {
1096  free(event_table->native_events[i].mask_description);
1097  }
1098  }
1099 
1100  free(event_table->native_events);
1101 
1103 
1104  SUBDBG("EXIT: PAPI_OK\n");
1105  return PAPI_OK;
1106 }
struct native_event_t * native_events
return PAPI_OK
Definition: linux-nvml.c:497
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
int i
Definition: fileop.c:140
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
#define PAPI_PMU_MAX
Definition: papi.h:469
free(dummyfile[xx])
char * pmu_names[PAPI_PMU_MAX]
Definition: papi.h:650
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define NAMELIB_LOCK
Definition: papi_internal.h:94

Here is the call graph for this function:

Here is the caller graph for this function:

int _peu_libpfm4_init ( papi_vector_t my_vector,
int  cidx,
struct native_event_table_t event_table,
int  pmu_type 
)

Definition at line 1259 of file pe_libpfm4_events.c.

1261  {
1262 
1263  int detected_pmus=0;
1264  int i;
1265  int j=0;
1266  pfm_err_t retval = PFM_SUCCESS;
1267  unsigned int ncnt;
1268  pfm_pmu_info_t pinfo;
1269 
1270  (void)cidx;
1271 
1272  /* allocate the native event structure */
1273 
1274  event_table->num_native_events=0;
1275  event_table->pmu_type=pmu_type;
1276 
1277  event_table->native_events=calloc(NATIVE_EVENT_CHUNK,
1278  sizeof(struct native_event_t));
1279  if (event_table->native_events==NULL) {
1280  return PAPI_ENOMEM;
1281  }
1283 
1284  /* Count number of present PMUs */
1285  detected_pmus=0;
1286  ncnt=0;
1287 
1288  my_vector->cmp_info.num_cntrs=0;
1289 
1290  SUBDBG("Detected pmus:\n");
1291  i=0;
1292  while(1) {
1293  memset(&pinfo,0,sizeof(pfm_pmu_info_t));
1294  pinfo.size = sizeof(pfm_pmu_info_t);
1295  retval=pfm_get_pmu_info(i, &pinfo);
1296 
1297  /* We're done if we hit an invalid PMU entry */
1298  /* We can't check against PFM_PMU_MAX */
1299  /* as that might not match if libpfm4 is dynamically linked */
1300 
1301  if (retval==PFM_ERR_INVAL) {
1302  break;
1303  }
1304 
1305  if ((retval==PFM_SUCCESS) && (pinfo.name != NULL) &&
1306  (pmu_is_present_and_right_type(&pinfo,pmu_type))) {
1307 
1308  SUBDBG("\t%d %s %s %d\n",i,pinfo.name,pinfo.desc,pinfo.type);
1309 
1310  detected_pmus++;
1311  ncnt+=pinfo.nevents;
1312 
1313  if ((j < PAPI_PMU_MAX) && (pinfo.name != NULL)) {
1314  my_vector->cmp_info.pmu_names[j++] = strdup(pinfo.name);
1315  }
1316  my_vector->cmp_info.num_cntrs += pinfo.num_cntrs+
1317  pinfo.num_fixed_cntrs;
1318  }
1319  i++;
1320  }
1321  SUBDBG("%d native events detected on %d pmus\n",ncnt,detected_pmus);
1322 
1323  my_vector->cmp_info.num_native_events = ncnt;
1324 
1325  SUBDBG( "num_counters: %d\n", my_vector->cmp_info.num_cntrs );
1326 
1327  return PAPI_OK;
1328 }
struct native_event_t * native_events
#define NATIVE_EVENT_CHUNK
return PAPI_OK
Definition: linux-nvml.c:497
void
Definition: iozone.c:18627
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
static int cidx
int i
Definition: fileop.c:140
#define PAPI_PMU_MAX
Definition: papi.h:469
char * pmu_names[PAPI_PMU_MAX]
Definition: papi.h:650
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define PAPI_ENOMEM
Definition: papi.h:254
static int pmu_is_present_and_right_type(pfm_pmu_info_t *pinfo, int type)
long j
Definition: iozone.c:19135
ssize_t retval
Definition: libasync.c:338

Here is the call graph for this function:

Here is the caller graph for this function:

static struct native_event_t* allocate_native_event ( const char *  name,
int  libpfm4_index,
int  cidx,
struct native_event_table_t event_table 
)
static

Definition at line 127 of file pe_libpfm4_events.c.

130  {
131 
132  SUBDBG("ENTER: name: %s, libpfm4_index: %#x, event_table: %p, "
133  "event_table->pmu_type: %d\n",
134  name, libpfm4_index, event_table, event_table->pmu_type);
135 
136  int nevt_idx;
137  int event_num;
138  int encode_failed=0;
139 
140  pfm_err_t ret;
141  char *event_string=NULL;
142  char *pmu_name;
143  char *event;
144  char *masks;
145  char fullname[BUFSIZ];
146  struct native_event_t *ntv_evt;
147 
148  pfm_perf_encode_arg_t perf_arg;
149  pfm_event_info_t einfo;
150  pfm_event_attr_info_t ainfo;
151  pfm_pmu_info_t pinfo;
152 
153  // if no place to put native events, report that allocate failed
154  if (event_table->native_events==NULL) {
155  SUBDBG("EXIT: no place to put native events\n");
156  return NULL;
157  }
158 
159  // find out if this event is already known
160  event_num=find_existing_event(name, event_table);
161 
162  /* add the event to our event table */
164 
165  // if we already know this event name,
166  // it was created as part of setting up the preset tables
167  // we need to use the event table which is already created
168  if (event_num >= 0) {
169  nevt_idx = event_num;
170  ntv_evt = &(event_table->native_events[event_num]);
171  } else {
172  // set to use a new event table
173  // (count of used events not bumped
174  // until we are sure setting it up does not get an errror)
175  nevt_idx = event_table->num_native_events;
176  ntv_evt = &(event_table->native_events[nevt_idx]);
177  }
178 
179  SUBDBG("event_num: %d, nevt_idx: %d, ntv_evt: %p\n",
180  event_num, nevt_idx, ntv_evt);
181 
182  /* clear the argument and attribute structures */
183  memset(&perf_arg,0,sizeof(pfm_perf_encode_arg_t));
184  memset(&(ntv_evt->attr),0,sizeof(struct perf_event_attr));
185 
186  // set argument structure fields so the encode
187  // function can give us what we need
188  perf_arg.attr=&ntv_evt->attr;
189  perf_arg.fstr=&event_string;
190 
191  /* use user provided name of the event to get the */
192  /* perf_event encoding and a fully qualified event string */
193  ret = pfm_get_os_event_encoding(name,
194  PFM_PLM0 | PFM_PLM3,
195  PFM_OS_PERF_EVENT_EXT,
196  &perf_arg);
197 
198  // If the encode function failed, skip processing of the event_string
199  if ((ret != PFM_SUCCESS) || (event_string == NULL)) {
200  SUBDBG("encode failed for event: %s, returned: %d\n",
201  name, ret);
202 
203  // we need to remember that this event encoding failed
204  // but still create the native event table
205  // the event table is used by the list so we put what we
206  // can get into it
207  // but the failure doing the encode causes us to
208  // return null to our caller
209  encode_failed = 1;
210 
211  // Noting the encode_failed error in the attr.config allows
212  // any later validate attempts to return an error value
213 
214  // ??? .config is 64-bits? --vmw
215  ntv_evt->attr.config = 0xFFFFFF;
216 
217  // we also want to make it look like a cpu number
218  // was not provided as an event mask
219  perf_arg.cpu = -1;
220 
221  // Why don't we just return NULL here? --vmw
222  //return NULL;
223  }
224 
225  // get a copy of the event name and break it up into its parts
226  event_string = strdup(name);
227 
228  SUBDBG("event_string: %s\n", event_string);
229 
230  // get the pmu name, event name and mask list pointers
231  // from the event string
232  event = strstr (event_string, "::");
233  if (event != NULL) {
234  *event = 0; // null terminate pmu name
235  event += 2; // event name follows '::'
236  pmu_name = strdup(event_string);
237  } else {
238  // no pmu name in event string
239  pmu_name = malloc(2);
240  pmu_name[0] = 0;
241  event = event_string;
242  }
243  masks = strstr (event, ":");
244  if (masks != NULL) {
245  *masks = 0; // null terminate event name
246  masks += 1; // masks follow :
247  } else {
248  masks = "";
249  }
250 
251  // build event name to find, put a pmu name on it if we have one
252  if (strlen(pmu_name) == 0) {
253  sprintf(fullname,"%s", event);
254  } else {
255  sprintf(fullname,"%s::%s", pmu_name, event);
256  }
257 
258  SUBDBG("pmu_name: %s, event: %s, masks: %s, fullname: %s\n",
259  pmu_name, event, masks, fullname);
260 
261  // if the libpfm4 index was not provided,
262  // try to get one based on the event name passed in.
263 
264  /* This may return a value for a disabled PMU */
265  if (libpfm4_index == -1) {
266  libpfm4_index = pfm_find_event(fullname);
267  if (libpfm4_index < 0) {
268  free(event_string);
269  free(pmu_name);
271  SUBDBG("EXIT: error from libpfm4 find event\n");
272  return NULL;
273  }
274  SUBDBG("libpfm4_index: %#x\n", libpfm4_index);
275  }
276 
277  // get this events information from libpfm4,
278  // if unavailable return event not found (structure be zeroed)
279  memset( &einfo, 0, sizeof( pfm_event_info_t ));
280  einfo.size = sizeof(pfm_event_info_t);
281  if ((ret = pfm_get_event_info(libpfm4_index,
282  PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
283  free(event_string);
284  free(pmu_name);
286  SUBDBG("EXIT: pfm_get_event_info failed with %d\n", ret);
287  return NULL;
288  }
289 
290  // if pmu type is not one supported by this component,
291  // return event not found (structure be zeroed)
292  memset(&pinfo,0,sizeof(pfm_pmu_info_t));
293  pinfo.size = sizeof(pfm_pmu_info_t);
294  pfm_get_pmu_info(einfo.pmu, &pinfo);
295  if (pmu_is_present_and_right_type(&pinfo, event_table->pmu_type) == 0) {
296  free(event_string);
297  free(pmu_name);
299  SUBDBG("EXIT: PMU not supported by this component: einfo.pmu: %d, PFM_PMU_TYPE_CORE: %d\n", einfo.pmu, PFM_PMU_TYPE_CORE);
300  return NULL;
301  }
302 
303  ntv_evt->allocated_name=strdup(name);
304  ntv_evt->mask_string=strdup(masks);
305  ntv_evt->component=cidx;
306  ntv_evt->pmu=pmu_name;
307  ntv_evt->base_name=strdup(event);
308  ntv_evt->pmu_plus_name=strdup(fullname);
309  ntv_evt->libpfm4_idx=libpfm4_index;
310  ntv_evt->event_description=strdup(einfo.desc);
311  ntv_evt->users=0; /* is this needed? */
312  ntv_evt->cpu=perf_arg.cpu;
313 
314  SUBDBG("ntv_evt->mask_string: %p (%s)\n",
315  ntv_evt->mask_string, ntv_evt->mask_string);
316  char *msk_ptr = strdup(masks); // get a work copy of the mask string before we free the space it was in
317  free(event_string);
318 
319  char mask_desc[PAPI_HUGE_STR_LEN] = "";
320 
321  // if there is any mask data, collect their descriptions
322  if ((msk_ptr != NULL) && (strlen(msk_ptr) > 0)) {
323  // go get the descriptions for each of the
324  // masks provided with this event
325  char *ptr = msk_ptr;
326  SUBDBG("ptr: %p (%s)\n", ptr, ptr);
327  while (ptr != NULL) {
328  char *ptrm = strstr(ptr, ":");
329  if (ptrm != NULL) {
330  *ptrm = '\0';
331  ptrm++;
332  }
333 
334  // get the length of the mask name
335  char *wrk = strchr(ptr, '=');
336  unsigned int msk_name_len;
337  if (wrk != NULL) {
338  msk_name_len = wrk - ptr;
339  SUBDBG("Found =, length=%d\n",msk_name_len);
340  } else {
341  msk_name_len = strlen (ptr);
342  SUBDBG("No =, length=%d\n",msk_name_len);
343  }
344 
345  int i, mask_found=0;
346  for (i=0 ; i<einfo.nattrs ; i++) {
347  // get this events attribute information
348  // from libpfm4, if unavailable return
349  // event not found (table must be cleared)
350  memset (&ainfo, 0,
351  sizeof(pfm_event_attr_info_t));
352  ainfo.size = sizeof(pfm_event_attr_info_t);
353  ret = pfm_get_event_attr_info(libpfm4_index,
354  i, PFM_OS_PERF_EVENT_EXT, &ainfo);
355  if (ret != PFM_SUCCESS) {
356  free (msk_ptr);
357  SUBDBG("EXIT: Attribute info not found, libpfm4_index: %#x, ret: %d\n", libpfm4_index, _papi_libpfm4_error(ret));
358  // FIXME: do we need to unlock here? --vmw
359  return NULL;
360  }
361 
362  // if this is the one we want,
363  // append its description
364  if ((msk_name_len == strlen(ainfo.name)) &&
365  (strncmp(ptr, ainfo.name, msk_name_len) == 0)) {
366  mask_found=1;
367  SUBDBG("Found mask: libpfm4=%s -- matches %s -- i: %d, %d %zu\n",
368  ainfo.name, ptr, i, msk_name_len, strlen(ainfo.name));
369  // find out how much space is left in the mask description work buffer we are building
370  unsigned int mskleft = sizeof(mask_desc) - strlen(mask_desc);
371  // if no space left, just discard this mask description
372  if (mskleft <= 1) {
373  SUBDBG("EXIT: Attribute description discarded: %s\n", ainfo.desc);
374  break;
375  }
376  // if description buffer is not empty, put in mask description separator
377  if (strlen(mask_desc) > 0) {
378  strcat (mask_desc, ":");
379  mskleft--;
380  }
381  // if new description will not all fit in buffer, report truncation
382  if (mskleft < (strlen(ainfo.desc) + 1)) {
383  SUBDBG("EXIT: Attribute description truncated: %s\n", ainfo.desc);
384  }
385  // move as much of this description as will fit
386  strncat (mask_desc, ainfo.desc, mskleft-1);
387  mask_desc[mskleft-1] = '\0';
388  break;
389  }
390  }
391 
392  /* See if we had a mask that wasn't found */
393  if (!mask_found) {
394  SUBDBG("Mask not found! %s\n",ptr);
395  /* FIXME: do we need to unlock here? */
396  return NULL;
397  }
398 
399  // if we have filled the work buffer, we can quit now
400  if ( (sizeof(mask_desc) - strlen(mask_desc)) <= 1) {
401  break;
402  }
403  ptr = ptrm;
404  }
405  }
406  ntv_evt->mask_description=strdup(mask_desc);
407  SUBDBG("ntv_evt->mask_description: %p (%s)\n", ntv_evt->mask_description, ntv_evt->mask_description);
408 
409  // give back space if we got any
410  if (msk_ptr != NULL) {
411  free (msk_ptr);
412  }
413 
414  // create a papi table for this native event, put the index into the event sets array of native events into the papi table
415  int new_event_code = _papi_hwi_native_to_eventcode(cidx, libpfm4_index, nevt_idx, ntv_evt->allocated_name);
416  _papi_hwi_set_papi_event_string((const char *)ntv_evt->allocated_name);
417  _papi_hwi_set_papi_event_code(new_event_code, 1);
418 
419  ntv_evt->papi_event_code=new_event_code;
420 
421  SUBDBG("Using %#x as index for %s\n", ntv_evt->libpfm4_idx, fullname);
422  SUBDBG("num_native_events: %d, allocated_native_events: %d\n", event_table->num_native_events, event_table->allocated_native_events);
423  SUBDBG("Native Event: papi_event_code: %#x, libpfm4_idx: %#x, pmu: %s, base_name: %s, mask_string: %s, allocated_name: %s\n",
424  ntv_evt->papi_event_code, ntv_evt->libpfm4_idx, ntv_evt->pmu, ntv_evt->base_name, ntv_evt->mask_string, ntv_evt->allocated_name);
425  SUBDBG("event_table->native_events[%d]: %p, cpu: %d, attr.config: 0x%"PRIx64", attr.config1: 0x%"PRIx64", attr.config2: 0x%"PRIx64", attr.type: 0x%"PRIx32", attr.exclude_user: %d, attr.exclude_kernel: %d, attr.exclude_guest: %d\n",
426  nevt_idx, &(event_table->native_events[nevt_idx]), ntv_evt->cpu, ntv_evt->attr.config,
427  ntv_evt->attr.config1, ntv_evt->attr.config2, ntv_evt->attr.type,
428  ntv_evt->attr.exclude_user, ntv_evt->attr.exclude_kernel, ntv_evt->attr.exclude_guest);
429 
430  /* If we've used all of the allocated native events, */
431  /* then allocate more room */
432  if (event_table->num_native_events >=
433  event_table->allocated_native_events-1) {
434 
435  SUBDBG("Allocating more room for native events (%d %ld)\n",
437  (long)sizeof(struct native_event_t) *
439 
440  event_table->native_events=realloc(event_table->native_events,
441  sizeof(struct native_event_t) *
443 
445 
446  // we got new space so we need to reset
447  // the pointer to the correct native event in the new space
448  ntv_evt = &(event_table->native_events[nevt_idx]);
449  }
450 
451 
452  // if getting more space for native events failed,
453  // report that allocate failed
454  if (event_table->native_events==NULL) {
455  SUBDBG("EXIT: attempt to get more space for "
456  "native events failed\n");
457  return NULL;
458  }
459 
460  // if we created a new event, bump the number used
461  if (event_num < 0) {
462  event_table->num_native_events++;
463  }
464 
466 
467  if (encode_failed != 0) {
468  SUBDBG("EXIT: encoding event failed\n");
469  return NULL;
470  }
471 
472  SUBDBG("EXIT: new_event: %p\n", ntv_evt);
473  return ntv_evt;
474 }
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
struct native_event_t * native_events
#define NATIVE_EVENT_CHUNK
static int find_existing_event(const char *name, struct native_event_table_t *event_table)
int _papi_libpfm4_error(int pfm_error)
#define PAPI_HUGE_STR_LEN
Definition: papi.h:467
long long ret
Definition: iozone.c:1346
static int cidx
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)
free(dummyfile[xx])
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
strcat(command, mountname)
#define NAMELIB_LOCK
Definition: papi_internal.h:94
static int pmu_is_present_and_right_type(pfm_pmu_info_t *pinfo, int type)
void _papi_hwi_set_papi_event_code(unsigned int event_code, int update_flag)
perf_event_attr_t attr
char * name
Definition: iozone.c:23648
void _papi_hwi_set_papi_event_string(const char *event_string)
Definition: papi_internal.c:90
char * ptr
Definition: iozone.c:23586

Here is the call graph for this function:

Here is the caller graph for this function:

static int find_existing_event ( const char *  name,
struct native_event_table_t event_table 
)
static

Definition at line 46 of file pe_libpfm4_events.c.

47  {
48  SUBDBG("Entry: name: %s, event_table: %p, num_native_events: %d\n", name, event_table, event_table->num_native_events);
49 
50  int i,event=PAPI_ENOEVNT;
51 
53 
54  for(i=0;i<event_table->num_native_events;i++) {
55  // Most names passed in will contain the pmu name, so first we compare to the allocated name (it has pmu name on front)
56  if (!strcmp(name,event_table->native_events[i].allocated_name)) {
57  SUBDBG("Found allocated_name: %s, libpfm4_idx: %#x, papi_event_code: %#x\n",
58  event_table->native_events[i].allocated_name, event_table->native_events[i].libpfm4_idx, event_table->native_events[i].papi_event_code);
59  event=i;
60  break;
61  }
62  // some callers have an event name without the pmu name on the front, so we also compare to the base name (just the event name part)
63  if (!strcmp(name,event_table->native_events[i].base_name)) {
64  int nameLen = strlen(event_table->native_events[i].base_name);
65  // the name we are looking for must be the same length as this event table entry name for them to match
66  if (strlen(name) != nameLen + strlen(event_table->native_events[i].mask_string) + 1) {
67  continue;
68  }
69  if(!strcmp(name+nameLen+1, event_table->native_events[i].mask_string)) {
70  SUBDBG("Found base_name: %s, mask_string: %s, libpfm4_idx: %#x, papi_event_code: %#x\n",
71  event_table->native_events[i].base_name, event_table->native_events[i].mask_string , event_table->native_events[i].libpfm4_idx, event_table->native_events[i].papi_event_code);
72  event=i;
73  break;
74  }
75  }
76  }
78 
79  SUBDBG("EXIT: returned: %#x\n", event);
80  return event;
81 }
#define PAPI_ENOEVNT
Definition: papi.h:260
struct native_event_t * native_events
int i
Definition: fileop.c:140
inline_static int _papi_hwi_lock(int lck)
Definition: threads.h:64
inline_static int _papi_hwi_unlock(int lck)
Definition: threads.h:78
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define NAMELIB_LOCK
Definition: papi_internal.h:94
char * name
Definition: iozone.c:23648

Here is the call graph for this function:

Here is the caller graph for this function:

static int get_first_event_next_pmu ( int  pmu_idx,
int  pmu_type 
)
static

Definition at line 486 of file pe_libpfm4_events.c.

487 {
488  SUBDBG("ENTER: pmu_idx: %d, pmu_type: %d\n", pmu_idx, pmu_type);
489  int pidx, ret;
490 
491  pfm_pmu_info_t pinfo;
492 
493  // start looking at the next pmu in the list
494  pmu_idx++;
495 
496  /* We loop forever here and exit if pfm_get_pmu_info() fails. */
497  /* Before we only went up to PFM_PMU_MAX but this is set at */
498  /* compile time and might not reflect the number of PMUs if */
499  /* PAPI is dynamically linked against libpfm4. */
500  while(1) {
501 
502  /* clear the PMU structure (required by libpfm4) */
503  memset(&pinfo,0,sizeof(pfm_pmu_info_t));
504  pinfo.size = sizeof(pfm_pmu_info_t);
505  ret=pfm_get_pmu_info(pmu_idx, &pinfo);
506 
507  if (ret==PFM_ERR_INVAL) {
508  break;
509  }
510 
511  if ((ret==PFM_SUCCESS) && pmu_is_present_and_right_type(&pinfo,pmu_type)) {
512 
513  pidx=pinfo.first_event;
514  SUBDBG("First event in pmu: %s is %#x\n", pinfo.name, pidx);
515 
516  if (pidx<0) {
517  /* For some reason no events available */
518  /* despite the PMU being active. */
519  /* This can happen, for example with ix86arch */
520  /* inside of VMware */
521  }
522  else {
523  SUBDBG("EXIT: pidx: %#x\n", pidx);
524  return pidx;
525  }
526  }
527 
528  pmu_idx++;
529 
530  }
531 
532  SUBDBG("EXIT: PAPI_ENOEVNT\n");
533  return PAPI_ENOEVNT;
534 
535 }
#define PAPI_ENOEVNT
Definition: papi.h:260
long long ret
Definition: iozone.c:1346
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
static int pmu_is_present_and_right_type(pfm_pmu_info_t *pinfo, int type)

Here is the call graph for this function:

Here is the caller graph for this function:

static int pmu_is_present_and_right_type ( pfm_pmu_info_t *  pinfo,
int  type 
)
static

Definition at line 84 of file pe_libpfm4_events.c.

84  {
85  SUBDBG("ENTER: pinfo: %s %p, pinfo->is_present: %d, "
86  "pinfo->type: %#x, type: %#x\n",
87  pinfo->name, pinfo, pinfo->is_present, pinfo->type, type);
88  if (!pinfo->is_present) {
89 // SUBDBG("EXIT: not present\n");
90  return 0;
91  }
92 
93  if ((pinfo->type==PFM_PMU_TYPE_UNCORE) && (type&PMU_TYPE_UNCORE)) {
94 // SUBDBG("EXIT: found PFM_PMU_TYPE_UNCORE\n");
95  return 1;
96  }
97  if ((pinfo->type==PFM_PMU_TYPE_CORE) && (type&PMU_TYPE_CORE)) {
98 // SUBDBG("EXIT: found PFM_PMU_TYPE_CORE\n");
99  return 1;
100  }
101  if ((pinfo->type==PFM_PMU_TYPE_OS_GENERIC) && (type&PMU_TYPE_OS)) {
102 // SUBDBG("EXIT: found PFM_PMU_TYPE_OS_GENERIC\n");
103  return 1;
104  }
105 
106 // SUBDBG("EXIT: not right type\n");
107  return 0;
108 }
#define PMU_TYPE_OS
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define PMU_TYPE_CORE
#define PMU_TYPE_UNCORE

Here is the caller graph for this function:

Variable Documentation

int attr_idx
static

Definition at line 32 of file pe_libpfm4_events.c.