pe_libpfm4_events.c File Reference

Include dependency graph for pe_libpfm4_events.c:

Go to the source code of this file.

Defines

#define NATIVE_EVENT_CHUNK   1024

Functions

static int find_existing_event (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 (char *name, int libpfm4_index, 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 (char *name, unsigned int *event_code, 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, 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 *my_vector, int cidx, struct native_event_table_t *event_table, int pmu_type)

Variables

static int attr_idx

Define Documentation

#define NATIVE_EVENT_CHUNK   1024

Definition at line 30 of file pe_libpfm4_events.c.


Function Documentation

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

Definition at line 1051 of file pe_libpfm4_events.c.

01053                          {
01054 
01055    int detected_pmus=0, found_default=0;
01056    int i;
01057    int j=0;
01058    pfm_err_t retval = PFM_SUCCESS;
01059    unsigned int ncnt;
01060    pfm_pmu_info_t pinfo;
01061 
01062    /* allocate the native event structure */
01063 
01064    event_table->num_native_events=0;
01065    event_table->pmu_type=pmu_type;
01066 
01067    event_table->native_events=calloc(NATIVE_EVENT_CHUNK,
01068                        sizeof(struct native_event_t));
01069    if (event_table->native_events==NULL) {
01070       return PAPI_ENOMEM;
01071    }
01072    event_table->allocated_native_events=NATIVE_EVENT_CHUNK;
01073 
01074    /* Count number of present PMUs */
01075    detected_pmus=0;
01076    ncnt=0;
01077 
01078    /* init default pmu */
01079    /* need to init pinfo or pfmlib might complain */
01080    memset(&(event_table->default_pmu), 0, sizeof(pfm_pmu_info_t));
01081    event_table->default_pmu.size = sizeof(pfm_pmu_info_t);
01082    retval=pfm_get_pmu_info(0, &(event_table->default_pmu));
01083    
01084    SUBDBG("Detected pmus:\n");
01085    for(i=0;i<PFM_PMU_MAX;i++) {
01086       memset(&pinfo,0,sizeof(pfm_pmu_info_t));
01087       pinfo.size = sizeof(pfm_pmu_info_t);
01088       retval=pfm_get_pmu_info(i, &pinfo);
01089       if ((retval!=PFM_SUCCESS) || (pinfo.name == NULL)) {
01090      continue;
01091       }
01092 
01093       if (pmu_is_present_and_right_type(&pinfo,pmu_type)) {
01094      SUBDBG("\t%d %s %s %d\n",i,pinfo.name,pinfo.desc,pinfo.type);
01095 
01096          detected_pmus++;
01097      ncnt+=pinfo.nevents;
01098 
01099      if (j < PAPI_PMU_MAX) {
01100          my_vector->cmp_info.pmu_names[j++] = strdup(pinfo.name);
01101      }
01102        
01103          if (pmu_type&PMU_TYPE_CORE) {
01104 
01105         /* Hack to have "default" PMU */
01106         if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
01107                   strcmp(pinfo.name,"ix86arch")) {
01108 
01109            SUBDBG("\t  %s is default\n",pinfo.name);
01110            memcpy(&(event_table->default_pmu),
01111               &pinfo,sizeof(pfm_pmu_info_t));
01112            found_default++;
01113         }
01114      }
01115          if (pmu_type==PMU_TYPE_UNCORE) {
01116          /* To avoid confusion, no "default" CPU for uncore */
01117            found_default=1;
01118      }
01119       }
01120    }
01121    SUBDBG("%d native events detected on %d pmus\n",ncnt,detected_pmus);
01122 
01123    if (!found_default) {
01124       SUBDBG("Could not find default PMU\n");
01125       return PAPI_ECMP;
01126    }
01127 
01128    if (found_default>1) {
01129      PAPIERROR("Found too many default PMUs!\n");
01130      return PAPI_ECMP;
01131    }
01132 
01133    my_vector->cmp_info.num_native_events = ncnt;
01134 
01135    my_vector->cmp_info.num_cntrs = event_table->default_pmu.num_cntrs+
01136                                    event_table->default_pmu.num_fixed_cntrs;
01137 
01138    SUBDBG( "num_counters: %d\n", my_vector->cmp_info.num_cntrs );
01139    
01140    /* Setup presets, only if Component 0 */
01141    if (cidx==0) {
01142       retval = _papi_load_preset_table( (char *)event_table->default_pmu.name, 
01143                      event_table->default_pmu.pmu, cidx );
01144       if ( retval ) {
01145          return retval;
01146       }
01147    }
01148 
01149    return PAPI_OK;
01150 }

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 631 of file pe_libpfm4_events.c.

00634 {
00635     SUBDBG("ENTER: EventCode: %#x, ntv_descr: %p, len: %d: event_table: %p\n", EventCode, ntv_descr, len, event_table);
00636 
00637     int eidx;
00638     int papi_event_code;
00639 
00640     // get the attribute index for this papi event
00641     papi_event_code = _papi_hwi_get_papi_event_code();
00642 
00643     // a papi event code less than 0 is invalid, return error
00644     if (papi_event_code <= 0) {
00645         SUBDBG("EXIT: PAPI_ENOEVNT\n");
00646         return PAPI_ENOEVNT;
00647     }
00648 
00649     // find our native event table for this papi event code (search list backwards because it improves chances of finding it quickly)
00650     for (eidx=event_table->num_native_events-1 ; eidx>=0 ; eidx--) {
00651         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);
00652         if ((papi_event_code == event_table->native_events[eidx].papi_event_code) && (EventCode == ((unsigned)event_table->native_events[eidx].libpfm4_idx))) {
00653             break;
00654         }
00655     }
00656 
00657     // if we did not find a match, return an error
00658     if (eidx < 0) {
00659         // If we did not find a match in our native event table, then the code passed in has not been
00660         // allocated yet  It should not be possible to get to this code.  The user has to call the papi
00661         // code_to_name api with a papi event code for a native event.  But the only way to get one of
00662         // those is to call either name_to_code or enum_cmp_events first.  When one of these calls is
00663         // done we allocate the event so it should always be there.
00664 
00665         SUBDBG("EXIT: PAPI_ENOEVNT\n");
00666         return PAPI_ENOEVNT;
00667     }
00668 
00669     char *edesc = event_table->native_events[eidx].event_description;
00670 
00671     // if it will not fit, return error
00672     if (strlen (edesc) >= (unsigned)len) {
00673         SUBDBG("EXIT: event name %s will not fit in buffer provided\n", edesc);
00674         return PAPI_EBUF;
00675     }
00676     strcpy (ntv_descr, edesc);
00677 
00678     // if this event had masks, also add their descriptions
00679     char *mdesc = event_table->native_events[eidx].mask_description;
00680     if ((mdesc != NULL)  &&  (strlen(mdesc) > 0)) {
00681         if ((strlen(edesc) + 8 + strlen(mdesc)) >= (unsigned)len) {
00682             SUBDBG("EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (unsigned)(strlen(edesc) + 8 + strlen(mdesc)), (unsigned)len);
00683             return PAPI_EBUF;
00684         }
00685         strcat (ntv_descr, ", masks:");
00686         strcat (ntv_descr, mdesc);
00687     }
00688 
00689     SUBDBG("EXIT: event description: %s\n", ntv_descr);
00690     return PAPI_OK;
00691 }

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 695 of file pe_libpfm4_events.c.

00698 {
00699     SUBDBG("ENTER: EventCode: %#x, info: %p, event_table: %p\n", EventCode, info, event_table);
00700 
00701     int ret;
00702 
00703     // get the event name first
00704     if ((ret = _pe_libpfm4_ntv_code_to_name(EventCode, info->symbol, sizeof(info->symbol), event_table)) != PAPI_OK) {
00705         SUBDBG("EXIT: _pe_libpfm4_ntv_code_to_name returned: %d\n", ret);
00706         return PAPI_ENOEVNT;
00707     }
00708 
00709     if ((ret = _pe_libpfm4_ntv_code_to_descr(EventCode, info->long_descr, sizeof(info->long_descr), event_table)) != PAPI_OK) {
00710         SUBDBG("EXIT: _pe_libpfm4_ntv_code_to_descr returned: %d\n", ret);
00711         return PAPI_ENOEVNT;
00712     }
00713 
00714     SUBDBG("EXIT: EventCode: %#x, name: %s, desc: %s\n", EventCode, info->symbol, info->long_descr);
00715     return PAPI_OK;
00716 }

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 538 of file pe_libpfm4_events.c.

00541 {
00542     SUBDBG("ENTER: EventCode: %#x, ntv_name: %p, len: %d, event_table: %p\n", EventCode, ntv_name, len, event_table);
00543 
00544     int eidx;
00545     int papi_event_code;
00546 
00547     // get the attribute index for this papi event
00548     papi_event_code = _papi_hwi_get_papi_event_code();
00549 
00550     // a papi event code less than 0 is invalid, return error
00551     if (papi_event_code <= 0) {
00552         SUBDBG("EXIT: PAPI_ENOEVNT\n");
00553         return PAPI_ENOEVNT;
00554     }
00555 
00556     // find our native event table for this papi event code (search list backwards because it improves chances of finding it quickly)
00557     for (eidx=event_table->num_native_events-1 ; eidx>=0 ; eidx--) {
00558         if ((papi_event_code == event_table->native_events[eidx].papi_event_code) && (EventCode == ((unsigned)event_table->native_events[eidx].libpfm4_idx))) {
00559             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);
00560             break;
00561         }
00562     }
00563 
00564     // if we did not find a match, return an error
00565     if (eidx < 0) {
00566         // If we did not find a match in our native event table, then the code passed in has not been
00567         // allocated yet  It should not be possible to get to this code.  The user has to call the papi
00568         // code_to_name api with a papi event code for a native event.  But the only way to get one of
00569         // those is to call either name_to_code or enum_cmp_events first.  When one of these calls is
00570         // done we allocate the event so it should always be there.
00571 
00572         SUBDBG("EXIT: PAPI_ENOEVNT\n");
00573         return PAPI_ENOEVNT;
00574     }
00575 
00576     // if this event is defined by the default pmu, then use only the event name
00577     // if it is not defined by the default pmu, then use both the pmu name and event name
00578     char *ename;
00579     if (strcmp(event_table->default_pmu.name, event_table->native_events[eidx].pmu) == 0) {
00580         ename = event_table->native_events[eidx].base_name;
00581     } else {
00582         ename = event_table->native_events[eidx].pmu_plus_name;
00583     }
00584 
00585     // if it will not fit, return error
00586     if (strlen (ename) >= (unsigned)len) {
00587         SUBDBG("EXIT: event name %s will not fit in buffer provided\n", ename);
00588         return PAPI_EBUF;
00589     }
00590     strcpy (ntv_name, ename);
00591 
00592     // if this event had masks, also add their names
00593     char *mname = event_table->native_events[eidx].mask_string;
00594     if ((mname != NULL)  &&  (strlen(mname) > 0)) {
00595         if ((strlen(ename) + 8 + strlen(mname)) >= (unsigned)len) {
00596             SUBDBG("EXIT: Not enough room for event and mask descriptions: need: %u, have: %u", (unsigned)(strlen(ename) + 8 + strlen(mname)), (unsigned)len);
00597             return PAPI_EBUF;
00598         }
00599         strcat (ntv_name, ":");
00600         strcat (ntv_name, mname);
00601     }
00602 
00603     SUBDBG("EXIT: event name: %s\n", ntv_name);
00604     return PAPI_OK;
00605 }

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,
struct native_event_table_t event_table 
)

Definition at line 736 of file pe_libpfm4_events.c.

00738                                                              {
00739 
00740     SUBDBG("ENTER: PapiEventCode: %p, *PapiEventCode: %#x, modifier: %d, event_table: %p\n", PapiEventCode, *PapiEventCode, modifier, event_table);
00741 
00742     int code,ret, pnum;
00743     int max_umasks;
00744     char event_string[BUFSIZ];
00745     pfm_pmu_info_t pinfo;
00746     pfm_event_info_t einfo;
00747     struct native_event_t *our_event;
00748 
00749     /* return first event if so specified */
00750     if ( modifier == PAPI_ENUM_FIRST ) {
00751         attr_idx = 0;   // set so if they want attribute information, it will start with the first attribute
00752         code=get_first_event_next_pmu(-1, event_table->pmu_type);
00753        if (code < 0 ) {
00754            SUBDBG("EXIT: Invalid component first event code: %d\n", code);
00755           return code;
00756        }
00757 
00758         // get the event information from libpfm4 (must zero structure)
00759         memset( &einfo, 0, sizeof( pfm_event_info_t ));
00760         einfo.size = sizeof(pfm_event_info_t);
00761         if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
00762             SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
00763             return PAPI_ENOIMPL;
00764         }
00765 
00766         // get the pmu information from libpfm4 (must zero structure)
00767         memset( &pinfo, 0, sizeof(pfm_pmu_info_t) );
00768         pinfo.size = sizeof(pfm_pmu_info_t);
00769         ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
00770         if (ret!=PFM_SUCCESS) {
00771             SUBDBG("EXIT: pfm_get_pmu_info returned: %d\n", ret);
00772             return ret;
00773         }
00774 
00775         // build full event name
00776         sprintf (event_string, "%s::%s", pinfo.name, einfo.name);
00777         SUBDBG("code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
00778 
00779         // go allocate this event, need to create tables used by the get event info call that will probably follow
00780         if ((our_event = allocate_native_event(event_string, code, event_table)) == NULL) {
00781             // allocate may have created the event table but returned NULL to tell the caller the event string was invalid (attempt to encode it failed).
00782             // if the caller wants to use this event to count something, it will report an error
00783             // but if the caller is just interested in listing the event, then we need an event table with an event name and libpfm4 index
00784             int evt_idx;
00785             if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
00786                 SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
00787                 return PAPI_ENOEVNT;
00788             }
00789 
00790             // give back the new event code
00791             *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
00792             SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
00793             return PAPI_OK;
00794         }
00795 
00796         *PapiEventCode = our_event->libpfm4_idx;
00797 
00798         SUBDBG("EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
00799         return PAPI_OK;
00800     }
00801 
00802     /* Handle looking for the next event */
00803     if ( modifier == PAPI_ENUM_EVENTS ) {
00804         attr_idx = 0;   // set so if they want attribute information, it will start with the first attribute
00805 
00806         // get the next event code from libpfm4, if there are no more in this pmu find first event in next pmu
00807         if ((code = pfm_get_event_next(*PapiEventCode)) < 0) {
00808 
00809             // get this events information from libpfm4, we need the pmu number of the last event we processed (table must be cleared)
00810             memset( &einfo, 0, sizeof( pfm_event_info_t ));
00811             einfo.size = sizeof(pfm_event_info_t);
00812             if ((ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
00813                 SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
00814                 return PAPI_ENOIMPL;
00815             }
00816             SUBDBG("*PapiEventCode: %#x, event: %s\n", *PapiEventCode, einfo.name);
00817 
00818             // get the pmu number of the last event
00819             pnum = einfo.pmu;
00820 
00821             while ( pnum<PFM_PMU_MAX) {
00822                 SUBDBG("pnum: %d\n", pnum);
00823                 code=get_first_event_next_pmu(pnum, event_table->pmu_type);
00824                 if (code < 0) {
00825                     SUBDBG("EXIT: No more pmu's to list, returning: %d\n", code);
00826                     return code;
00827                 }
00828                 break;
00829             }
00830         }
00831 
00832 
00833         // get the event information from libpfm4 (must zero structure)
00834         memset( &einfo, 0, sizeof( pfm_event_info_t ));
00835         einfo.size = sizeof(pfm_event_info_t);
00836         if ((ret = pfm_get_event_info(code, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
00837             SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
00838             return PAPI_ENOIMPL;
00839         }
00840 
00841         // get the pmu information from libpfm4 (must zero structure)
00842         memset( &pinfo, 0, sizeof(pfm_pmu_info_t) );
00843         pinfo.size = sizeof(pfm_pmu_info_t);
00844         ret=pfm_get_pmu_info(einfo.pmu, &pinfo);
00845         if (ret!=PFM_SUCCESS) {
00846             SUBDBG("EXIT: pfm_get_pmu_info returned: %d\n", ret);
00847             return ret;
00848         }
00849 
00850         // build full event name
00851         sprintf (event_string, "%s::%s", pinfo.name, einfo.name);
00852         SUBDBG("code: %#x, pmu: %s, event: %s, event_string: %s\n", code, pinfo.name, einfo.name, event_string);
00853 
00854         // go allocate this event, need to create tables used by the get event info call that will follow
00855         if ((our_event = allocate_native_event(event_string, code, event_table)) == NULL) {
00856             // allocate may have created the event table but returned NULL to tell the caller the event string was invalid (attempt to encode it failed).
00857             // if the caller wants to use this event to count something, it will report an error
00858             // but if the caller is just interested in listing the event, then we need an event table with an event name and libpfm4 index
00859             int evt_idx;
00860             if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
00861                 SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
00862                 return PAPI_ENOEVNT;
00863             }
00864 
00865             // give back the new event code
00866             *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
00867             SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
00868             return PAPI_OK;
00869         }
00870 
00871         // give back the new event code
00872         *PapiEventCode = our_event->libpfm4_idx;
00873 
00874         SUBDBG("EXIT: *PapiEventCode: %#x\n", *PapiEventCode);
00875         return PAPI_OK;
00876     }
00877 
00878     /* We don't handle PAPI_NTV_ENUM_UMASK_COMBOS */
00879     if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) {
00880         SUBDBG("EXIT: do not support umask combos yet\n");
00881         return PAPI_ENOIMPL;
00882     } 
00883 
00884     /* Enumerate PAPI_NTV_ENUM_UMASKS (umasks on an event) */
00885     if ( modifier == PAPI_NTV_ENUM_UMASKS ) {
00886         // get this events information from libpfm4, we need the number of masks this event knows about (table must be cleared)
00887         memset( &einfo, 0, sizeof( pfm_event_info_t ));
00888         einfo.size = sizeof(pfm_event_info_t);
00889         if ((ret = pfm_get_event_info(*PapiEventCode, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
00890             SUBDBG("EXIT: pfm_get_event_info returned: %d\n", ret);
00891             return PAPI_ENOIMPL;
00892         }
00893 //      SUBDBG("*PapiEventCode: %#x, einfo.name: %s, einfo.code: %#x, einfo.nattrs: %d\n", *PapiEventCode, einfo.name, einfo.code, einfo.nattrs);
00894 
00895         // set max number of masks
00896         max_umasks = einfo.nattrs;
00897 
00898         // if we reached last attribute, return error to show we are done with this events masks
00899         if (attr_idx == max_umasks) {
00900             SUBDBG("EXIT: already processed all umasks: attr_idx: %d\n", attr_idx);
00901             return PAPI_ENOEVNT;
00902         }
00903 
00904         // find the event table for this event, we need the pmu name and event name without any masks
00905         int ntv_idx = _papi_hwi_get_ntv_idx(_papi_hwi_get_papi_event_code());
00906         if (ntv_idx < 0) {
00907             SUBDBG("EXIT: _papi_hwi_get_ntv_idx returned: %d\n", ntv_idx);
00908             return ntv_idx;
00909         }
00910         char *ename = event_table->native_events[ntv_idx].pmu_plus_name;
00911         if ((ename == NULL)  ||  (strlen(ename) >= sizeof(event_string))) {
00912             SUBDBG("EXIT: Event name will not fit into buffer\n");
00913             return PAPI_EBUF;
00914         }
00915         strcpy (event_string, ename);
00916         SUBDBG("event_string: %s\n", event_string);
00917 
00918         // go get the attribute information for this event
00919         // libpfm4 likes the table cleared
00920         pfm_event_attr_info_t ainfo;
00921         memset (&ainfo, 0, sizeof(pfm_event_attr_info_t));
00922         ainfo.size = sizeof(pfm_event_attr_info_t);
00923         ret = pfm_get_event_attr_info(*PapiEventCode, attr_idx, PFM_OS_PERF_EVENT_EXT, &ainfo);
00924         if (ret != PFM_SUCCESS) {
00925             SUBDBG("EXIT: Attribute info not found, EventCode: %#x, attr_idx: %d, ret: %d\n", *PapiEventCode, attr_idx, _papi_libpfm4_error(ret));
00926             return _papi_libpfm4_error(ret);
00927         }
00928         SUBDBG("*PapiEventCode: %#x, attr_idx: %d, type: %d, name: %s, description: %s\n", *PapiEventCode, attr_idx, ainfo.type, ainfo.name, ainfo.desc);
00929 
00930         if (strlen(event_string) + strlen(ainfo.name) + 35 > sizeof(event_string)) {
00931             SUBDBG("EXIT: Event name and mask will not fit into buffer\n");
00932             return PAPI_EBUF;
00933         }
00934 
00935         strcat (event_string, ":");
00936         strcat (event_string, ainfo.name);
00937         switch (ainfo.type) {
00938             case PFM_ATTR_UMASK:
00939                 break;
00940             case PFM_ATTR_MOD_BOOL:
00941             case PFM_ATTR_MOD_INTEGER:
00942                 // a few attributes require a non-zero value to encode correctly (most would accept zero here)
00943                 strcat(event_string,"=0");
00944                 break;
00945             default:
00946                 SUBDBG("EXIT: Unsupported attribute type: %d", ainfo.type);
00947                 return PAPI_EATTR;
00948         }
00949 
00950         // go allocate this event, need to create tables used by the get event info call that will follow
00951         if ((our_event = allocate_native_event(event_string, *PapiEventCode, event_table)) == NULL) {
00952             // allocate may have created the event table but returned NULL to tell the caller the event string was invalid.
00953             // if the caller wants to use this event to count something, it must report the error
00954             // 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
00955             int evt_idx;
00956             if ((evt_idx = find_existing_event(event_string, event_table)) < 0) {
00957                 SUBDBG("EXIT: Allocating event: '%s' failed\n", event_string);
00958                 return PAPI_ENOEVNT;
00959             }
00960             // bump so next time we will use next attribute
00961             attr_idx++;
00962             // give back the new event code
00963             *PapiEventCode = event_table->native_events[evt_idx].libpfm4_idx;
00964             SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
00965             return PAPI_OK;
00966         }
00967 
00968         // bump so next time we will use next attribute
00969         attr_idx++;
00970 
00971         // give back the new event code
00972         *PapiEventCode = our_event->libpfm4_idx;
00973 
00974         SUBDBG("EXIT: event code: %#x\n", *PapiEventCode);
00975         return PAPI_OK;
00976     }
00977 
00978     /* Enumerate PAPI_NTV_ENUM_GROUPS (groups on an event) */
00979     if ( modifier == PAPI_NTV_ENUM_GROUPS ) {
00980         SUBDBG("EXIT: do not support enumerating groups in this component\n");
00981         return PAPI_ENOIMPL;
00982     }
00983 
00984     /* An unknown enumeration method was indicated */
00985 
00986     SUBDBG("EXIT: Invalid modifier argument provided\n");
00987     return PAPI_ENOIMPL;
00988 }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 489 of file pe_libpfm4_events.c.

00491 {
00492   SUBDBG( "ENTER: name: %s, event_code: %p, *event_code: %#x, event_table: %p\n", name, event_code, *event_code, event_table);
00493 
00494   struct native_event_t *our_event;
00495   int event_num;
00496 
00497   // if we already know this event name, just return its native code
00498   event_num=find_existing_event(name, event_table);
00499   if (event_num >= 0) {
00500          *event_code=event_table->native_events[event_num].libpfm4_idx;
00501          // the following call needs to happen to prevent the internal layer from creating a new papi native event table
00502          _papi_hwi_set_papi_event_code(event_table->native_events[event_num].papi_event_code, 1);
00503          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);
00504          return PAPI_OK;
00505   }
00506 
00507      // Try to allocate this event to see if it is known by libpfm4, if allocate fails tell the caller it is not valid
00508      our_event=allocate_native_event(name, -1, event_table);
00509      if (our_event==NULL) {
00510          SUBDBG("EXIT: Allocating event: '%s' failed\n", name);
00511          return PAPI_ENOEVNT;
00512      }
00513 
00514      *event_code = our_event->libpfm4_idx;
00515      SUBDBG("EXIT: Found code: %#x\n",*event_code);
00516      return PAPI_OK;
00517 }

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 1002 of file pe_libpfm4_events.c.

01003                                                   {
01004   SUBDBG("ENTER: event_table: %p\n", event_table);
01005 
01006   int i;
01007 
01008   for (i=0 ; i<PAPI_PMU_MAX ; i++) {
01009       if (my_vector->cmp_info.pmu_names[i] != NULL) {
01010           free (my_vector->cmp_info.pmu_names[i]);
01011       }
01012   }
01013 
01014   /* clean out and free the native events structure */
01015   _papi_hwi_lock( NAMELIB_LOCK );
01016 
01017   /* free memory allocated with strdup or malloc */
01018   for( i=0; i<event_table->num_native_events; i++) {
01019      free(event_table->native_events[i].base_name);
01020      free(event_table->native_events[i].pmu_plus_name);
01021      free(event_table->native_events[i].pmu);
01022      free(event_table->native_events[i].allocated_name);
01023      free(event_table->native_events[i].mask_string);
01024      free(event_table->native_events[i].event_description);
01025      if (event_table->native_events[i].mask_description != NULL) {
01026           free(event_table->native_events[i].mask_description);
01027      }
01028   }
01029 
01030   free(event_table->native_events);
01031 
01032   _papi_hwi_unlock( NAMELIB_LOCK );
01033 
01034   SUBDBG("EXIT: PAPI_OK\n");
01035   return PAPI_OK;
01036 }

Here is the call graph for this function:

Here is the caller graph for this function:

static struct native_event_t* allocate_native_event ( char *  name,
int  libpfm4_index,
struct native_event_table_t event_table 
) [static, read]

Definition at line 124 of file pe_libpfm4_events.c.

00125                                                         {
00126 
00127   SUBDBG("ENTER: name: %s, libpfm4_index: %#x, event_table: %p, event_table->pmu_type: %d\n", name, libpfm4_index, event_table, event_table->pmu_type);
00128 
00129   int nevt_idx;
00130   int event_num;
00131   int encode_failed=0;
00132 
00133   pfm_err_t ret;
00134   char *event_string=NULL;
00135   char *pmu_name;
00136   char *event;
00137   char *masks;
00138   char fullname[BUFSIZ];
00139   struct native_event_t *ntv_evt;
00140 
00141   pfm_perf_encode_arg_t perf_arg;
00142   pfm_event_info_t einfo;
00143   pfm_event_attr_info_t ainfo;
00144   pfm_pmu_info_t pinfo;
00145 
00146   // if no place to put native events, report that allocate failed
00147   if (event_table->native_events==NULL) {
00148      SUBDBG("EXIT: no place to put native events\n");
00149      return NULL;
00150   }
00151 
00152   // find out if this event is already known
00153   event_num=find_existing_event(name, event_table);
00154 
00155   /* add the event to our event table */
00156   _papi_hwi_lock( NAMELIB_LOCK );
00157 
00158   // if we already know this event name, it was created as part of setting up the preset tables
00159   // we need to use the event table which is already created
00160   if (event_num >= 0) {
00161      nevt_idx = event_num;
00162      ntv_evt = &(event_table->native_events[event_num]);
00163   } else {
00164       // set to use a new event table (count of used events not bumped until we are sure setting it up does not get an errro)
00165      nevt_idx = event_table->num_native_events;
00166      ntv_evt = &(event_table->native_events[nevt_idx]);
00167   }
00168 
00169   SUBDBG("event_num: %d, nevt_idx: %d, ntv_evt: %p\n", event_num, nevt_idx, ntv_evt);
00170 
00171   /* clear the argument and attribute structures */
00172   memset(&perf_arg,0,sizeof(pfm_perf_encode_arg_t));
00173   memset(&(ntv_evt->attr),0,sizeof(struct perf_event_attr));
00174 
00175   // set argument structure fields so the encode function can give us what we need
00176   perf_arg.attr=&ntv_evt->attr;
00177 
00178   /* use user provided name of the event to get the perf_event encoding and a fully qualified event string */
00179   ret = pfm_get_os_event_encoding(name, 
00180                   PFM_PLM0 | PFM_PLM3, 
00181                   PFM_OS_PERF_EVENT_EXT,
00182                   &perf_arg);
00183 
00184   // If the encode function failed, skip processing of the event_string
00185   if (ret != PFM_SUCCESS) {
00186       SUBDBG("encode failed for event: %s, returned: %d\n", name, ret);
00187 
00188       // we need to remember that this event encoding failed but still create the native event table
00189       // the event table is used by the list so we put what we can get into it
00190       // but the failure doing the encode causes us to return null to our caller
00191       encode_failed = 1;
00192 
00193       // Noting the encode_failed error in the attr.config allows
00194       // any later validate attempts to return an error value
00195       ntv_evt->attr.config = 0xFFFFFF;
00196 
00197       // we also want to make it look like a cpu number was not provided as an event mask
00198       perf_arg.cpu = -1;
00199   }
00200 
00201   // get a copy of the event name and break it up into its parts
00202   event_string = strdup(name);
00203 
00204   SUBDBG("event_string: %s\n", event_string);
00205 
00206   // get the pmu name, event name and mask list pointers from the event string
00207   event = strstr (event_string, "::");
00208   if (event != NULL) {
00209     *event = 0;     // null terminate pmu name
00210     event += 2;     // event name follows '::'
00211     pmu_name = strdup(event_string);
00212   } else {
00213     // no pmu name in event string
00214     pmu_name = malloc(2);
00215     pmu_name[0] = 0;
00216     event = event_string;
00217   }
00218   masks = strstr (event, ":");
00219   if (masks != NULL) {
00220       *masks = 0;     // null terminate event name
00221       masks += 1;     // masks follow :
00222   } else {
00223       masks = "";
00224   }
00225 
00226   // build event name to find, put a pmu name on it if we have one
00227   if(strlen(pmu_name) == 0) {
00228       sprintf(fullname,"%s", event);
00229   } else {
00230       sprintf(fullname,"%s::%s", pmu_name, event);
00231   }
00232   SUBDBG("pmu_name: %s, event: %s, masks: %s, fullname: %s\n", pmu_name, event, masks, fullname);
00233 
00234   // if the libpfm4 index was not provided, try to get one based on the event name passed in.
00235   if (libpfm4_index == -1) {
00236       libpfm4_index = pfm_find_event(fullname);
00237       if (libpfm4_index < 0) {
00238           free(event_string);
00239           free(pmu_name);
00240           _papi_hwi_unlock( NAMELIB_LOCK );
00241           SUBDBG("EXIT: error from libpfm4 find event\n");
00242           return NULL;
00243       }
00244       SUBDBG("libpfm4_index: %#x\n", libpfm4_index);
00245   }
00246 
00247     // get this events information from libpfm4, if unavailable return event not found (structure be zeroed)
00248     memset( &einfo, 0, sizeof( pfm_event_info_t ));
00249     einfo.size = sizeof(pfm_event_info_t);
00250     if ((ret = pfm_get_event_info(libpfm4_index, PFM_OS_PERF_EVENT_EXT, &einfo)) != PFM_SUCCESS) {
00251         free(event_string);
00252         free(pmu_name);
00253         _papi_hwi_unlock( NAMELIB_LOCK );
00254         SUBDBG("EXIT: pfm_get_event_info failed with %d\n", ret);
00255         return NULL;
00256     }
00257 
00258     // if pmu type is not one supported by this component, return event not found (structure be zeroed)
00259     memset(&pinfo,0,sizeof(pfm_pmu_info_t));
00260     pinfo.size = sizeof(pfm_pmu_info_t);
00261     pfm_get_pmu_info(einfo.pmu, &pinfo);
00262     if (pmu_is_present_and_right_type(&pinfo, event_table->pmu_type) == 0) {
00263         free(event_string);
00264         free(pmu_name);
00265         _papi_hwi_unlock( NAMELIB_LOCK );
00266         SUBDBG("EXIT: PMU not supported by this component: einfo.pmu: %d, PFM_PMU_TYPE_CORE: %d\n", einfo.pmu, PFM_PMU_TYPE_CORE);
00267         return NULL;
00268     }
00269 
00270   ntv_evt->allocated_name=strdup(name);
00271   ntv_evt->mask_string=strdup(masks);
00272   ntv_evt->component=_pe_libpfm4_get_cidx();
00273   ntv_evt->pmu=pmu_name;
00274   ntv_evt->base_name=strdup(event);
00275   ntv_evt->pmu_plus_name=strdup(fullname);
00276   ntv_evt->libpfm4_idx=libpfm4_index;
00277   ntv_evt->event_description=strdup(einfo.desc);
00278   ntv_evt->users=0;      /* is this needed? */
00279   ntv_evt->cpu=perf_arg.cpu;
00280 
00281     SUBDBG("ntv_evt->mask_string: %p (%s)\n", ntv_evt->mask_string, ntv_evt->mask_string);
00282     char *msk_ptr = strdup(masks);      // get a work copy of the mask string before we free the space it was in
00283     free(event_string);
00284 
00285     // if there is any mask data, collect their descriptions
00286     if ((msk_ptr != NULL)  &&  (strlen(msk_ptr) > 0)) {
00287         // go get the descriptions for each of the masks provided with this event
00288         char mask_desc[PAPI_HUGE_STR_LEN] = "";
00289         char *ptr = msk_ptr;
00290         SUBDBG("ptr: %p (%s)\n", ptr, ptr);
00291         while (ptr != NULL) {
00292             char *ptrm = strstr(ptr, ":");
00293             if (ptrm != NULL) {
00294                 *ptrm = '\0';
00295                 ptrm++;
00296             }
00297 
00298             // get the length of the mask name
00299             char *wrk = strchr(ptr, '=');
00300             unsigned int msk_name_len;
00301             if (wrk != NULL) {
00302                 msk_name_len = wrk - ptr;
00303             } else {
00304                 msk_name_len = strlen (ptr);
00305             }
00306 
00307             int i;
00308             for (i=0 ; i<einfo.nattrs ; i++) {
00309                 // get this events attribute information from libpfm4, if unavailable return event not found (table must be cleared)
00310                 memset (&ainfo, 0, sizeof(pfm_event_attr_info_t));
00311                 ainfo.size = sizeof(pfm_event_attr_info_t);
00312                 ret = pfm_get_event_attr_info(libpfm4_index, i, PFM_OS_PERF_EVENT_EXT, &ainfo);
00313                 if (ret != PFM_SUCCESS) {
00314                     free (msk_ptr);
00315                     SUBDBG("EXIT: Attribute info not found, libpfm4_index: %#x, ret: %d\n", libpfm4_index, _papi_libpfm4_error(ret));
00316                     return NULL;
00317                 }
00318 
00319                 // if this is the one we want, append its description
00320                 if ((msk_name_len == strlen(ainfo.name))  && (strncmp(ptr, ainfo.name, msk_name_len) == 0)) {
00321                     SUBDBG("Found mask: %s, i: %d\n", ainfo.name, i);
00322                     // find out how much space is left in the mask description work buffer we are building
00323                     unsigned int mskleft = sizeof(mask_desc) - strlen(mask_desc);
00324                     // if no space left, just discard this mask description
00325                     if (mskleft <= 1) {
00326                         SUBDBG("EXIT: Attribute description discarded: %s\n", ainfo.desc);
00327                         break;
00328                     }
00329                     // if description buffer is not empty, put in mask description separator
00330                     if (strlen(mask_desc) > 0) {
00331                         strcat (mask_desc, ":");
00332                         mskleft--;
00333                     }
00334                     // if new description will not all fit in buffer, report truncation
00335                     if (mskleft < (strlen(ainfo.desc) + 1)) {
00336                         SUBDBG("EXIT: Attribute description truncated: %s\n", ainfo.desc);
00337                     }
00338                     // move as much of this description as will fit
00339                     strncat (mask_desc, ainfo.desc, mskleft-1);
00340                     mask_desc[mskleft-1] = '\0';
00341                     break;
00342                 }
00343             }
00344 
00345             // if we have filled the work buffer, we can quit now
00346             if ( (sizeof(mask_desc) - strlen(mask_desc))  <= 1) {
00347                 break;
00348             }
00349             ptr = ptrm;
00350         }
00351         ntv_evt->mask_description=strdup(mask_desc);
00352         SUBDBG("ntv_evt->mask_description: %p (%s)\n", ntv_evt->mask_description, ntv_evt->mask_description);
00353     }
00354 
00355     // give back space if we got any
00356     if (msk_ptr != NULL) {
00357         free (msk_ptr);
00358     }
00359 
00360     // create a papi table for this native event, put the index into the event sets array of native events into the papi table
00361     int new_event_code = _papi_hwi_native_to_eventcode(_pe_libpfm4_get_cidx(), libpfm4_index, nevt_idx, ntv_evt->allocated_name);
00362     _papi_hwi_set_papi_event_string((const char *)ntv_evt->allocated_name);
00363     _papi_hwi_set_papi_event_code(new_event_code, 1);
00364 
00365     ntv_evt->papi_event_code=new_event_code;
00366 
00367     SUBDBG("Using %#x as index for %s\n", ntv_evt->libpfm4_idx, fullname);
00368     SUBDBG("num_native_events: %d, allocated_native_events: %d\n", event_table->num_native_events, event_table->allocated_native_events);
00369     SUBDBG("Native Event: papi_event_code: %#x, libpfm4_idx: %#x, pmu: %s, base_name: %s, mask_string: %s, allocated_name: %s\n",
00370             ntv_evt->papi_event_code, ntv_evt->libpfm4_idx, ntv_evt->pmu, ntv_evt->base_name, ntv_evt->mask_string, ntv_evt->allocated_name);
00371     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",
00372         nevt_idx, &(event_table->native_events[nevt_idx]), ntv_evt->cpu, ntv_evt->attr.config,
00373         ntv_evt->attr.config1, ntv_evt->attr.config2, ntv_evt->attr.type,
00374         ntv_evt->attr.exclude_user, ntv_evt->attr.exclude_kernel, ntv_evt->attr.exclude_guest);
00375 
00376   /* If we've used all of the allocated native events, then allocate more room */
00377   if (event_table->num_native_events >=
00378       event_table->allocated_native_events-1) {
00379 
00380       SUBDBG("Allocating more room for native events (%d %ld)\n",
00381         (event_table->allocated_native_events+NATIVE_EVENT_CHUNK),
00382         (long)sizeof(struct native_event_t) *
00383         (event_table->allocated_native_events+NATIVE_EVENT_CHUNK));
00384 
00385       event_table->native_events=realloc(event_table->native_events,
00386                sizeof(struct native_event_t) *
00387                (event_table->allocated_native_events+NATIVE_EVENT_CHUNK));
00388       event_table->allocated_native_events+=NATIVE_EVENT_CHUNK;
00389 
00390       // we got new space so we need to reset the pointer to the correct native event in the new space
00391       ntv_evt = &(event_table->native_events[nevt_idx]);
00392    }
00393 
00394   _papi_hwi_unlock( NAMELIB_LOCK );
00395 
00396   // if getting more space for native events failed, report that allocate failed
00397   if (event_table->native_events==NULL) {
00398      SUBDBG("EXIT: attempt to get more space for native events failed\n");
00399      return NULL;
00400   }
00401 
00402   // if we created a new event, bump the number used
00403   if (event_num < 0) {
00404      event_table->num_native_events++;
00405   }
00406 
00407   if (encode_failed != 0) {
00408       SUBDBG("EXIT: encoding event failed\n");
00409       return NULL;
00410   }
00411 
00412   SUBDBG("EXIT: new_event: %p\n", ntv_evt);
00413   return ntv_evt;
00414 }

Here is the call graph for this function:

Here is the caller graph for this function:

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

Definition at line 47 of file pe_libpfm4_events.c.

00048                                                                          {
00049   SUBDBG("Entry: name: %s, event_table: %p, num_native_events: %d\n", name, event_table, event_table->num_native_events);
00050 
00051   int i,event=PAPI_ENOEVNT;
00052 
00053   _papi_hwi_lock( NAMELIB_LOCK );
00054 
00055   for(i=0;i<event_table->num_native_events;i++) {
00056     // Most names passed in will contain the pmu name, so first we compare to the allocated name (it has pmu name on front)
00057     if (!strcmp(name,event_table->native_events[i].allocated_name)) {
00058       SUBDBG("Found allocated_name: %s, libpfm4_idx: %#x, papi_event_code: %#x\n", 
00059          event_table->native_events[i].allocated_name, event_table->native_events[i].libpfm4_idx, event_table->native_events[i].papi_event_code);
00060       event=i;
00061       break;
00062     }
00063     // 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)
00064     if (!strcmp(name,event_table->native_events[i].base_name)) {
00065       int nameLen = strlen(event_table->native_events[i].base_name);
00066       // the name we are looking for must be the same length as this event table entry name for them to match
00067       if (strlen(name) != nameLen + strlen(event_table->native_events[i].mask_string) + 1) {
00068         continue;
00069       }
00070       if(!strcmp(name+nameLen+1, event_table->native_events[i].mask_string)) {
00071           SUBDBG("Found base_name: %s, mask_string: %s, libpfm4_idx: %#x, papi_event_code: %#x\n",
00072             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);
00073           event=i;
00074           break;
00075       }
00076     }
00077   }
00078   _papi_hwi_unlock( NAMELIB_LOCK );
00079 
00080   SUBDBG("EXIT: returned: %#x\n", event);
00081   return event;
00082 }

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 426 of file pe_libpfm4_events.c.

00427 {
00428     SUBDBG("ENTER: pmu_idx: %d, pmu_type: %d\n", pmu_idx, pmu_type);
00429   int pidx, ret;
00430 
00431   pfm_pmu_info_t pinfo;
00432 
00433   // start looking at the next pmu in the list
00434   pmu_idx++;
00435 
00436   while(pmu_idx<PFM_PMU_MAX) {
00437 
00438     /* clear the PMU structure (required by libpfm4) */
00439     memset(&pinfo,0,sizeof(pfm_pmu_info_t));
00440     pinfo.size = sizeof(pfm_pmu_info_t);
00441     ret=pfm_get_pmu_info(pmu_idx, &pinfo);
00442 
00443     if ((ret==PFM_SUCCESS) && pmu_is_present_and_right_type(&pinfo,pmu_type)) {
00444 
00445       pidx=pinfo.first_event;
00446       SUBDBG("First event in pmu: %s is %#x\n", pinfo.name, pidx);
00447 
00448       if (pidx<0) {
00449     /* For some reason no events available */
00450     /* despite the PMU being active.       */
00451         /* This can happen, for example with ix86arch */
00452     /* inside of VMware                           */
00453       }
00454       else {
00455          SUBDBG("EXIT: pidx: %#x\n", pidx);
00456          return pidx;
00457       }
00458     }
00459 
00460     pmu_idx++;
00461 
00462   }
00463 
00464   SUBDBG("EXIT: PAPI_ENOEVNT\n");
00465   return PAPI_ENOEVNT;
00466   
00467 }

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 85 of file pe_libpfm4_events.c.

00085                                                                           {
00086 //   SUBDBG("ENTER: pinfo: %p, pinfo->is_present: %d, pinfo->type: %#x, type: %#x\n", pinfo, pinfo->is_present, pinfo->type, type);
00087   if (!pinfo->is_present) {
00088 //    SUBDBG("EXIT: not present\n");
00089       return 0;
00090   }
00091 
00092   if ((pinfo->type==PFM_PMU_TYPE_UNCORE) && (type&PMU_TYPE_UNCORE)) {
00093 //    SUBDBG("EXIT: found PFM_PMU_TYPE_UNCORE\n");
00094       return 1;
00095   }
00096   if ((pinfo->type==PFM_PMU_TYPE_CORE) && (type&PMU_TYPE_CORE)) {
00097 //    SUBDBG("EXIT: found PFM_PMU_TYPE_CORE\n");
00098       return 1;
00099   }
00100   if ((pinfo->type==PFM_PMU_TYPE_OS_GENERIC) && (type&PMU_TYPE_OS)) {
00101 //    SUBDBG("EXIT: found PFM_PMU_TYPE_OS_GENERIC\n");
00102       return 1;
00103   }
00104 
00105 //  SUBDBG("EXIT: not right type\n");
00106   return 0;
00107 }

Here is the caller graph for this function:


Variable Documentation

int attr_idx [static]

Definition at line 33 of file pe_libpfm4_events.c.


Generated on 17 Nov 2016 for PAPI by  doxygen 1.6.1