PAPI  5.0.1.0
papi_libpfm4_events.c File Reference
Include dependency graph for papi_libpfm4_events.c:

Go to the source code of this file.

Data Structures

struct  native_event_t

Defines

#define NATIVE_EVENT_CHUNK   1024

Functions

static int find_existing_event (char *name)
static struct native_event_tfind_existing_event_by_number (int eventnum)
static int find_event_no_aliases (char *name)
static int find_next_no_aliases (int code)
static struct native_event_tallocate_native_event (char *name, int event_idx)
static int find_max_umask (struct native_event_t *current_event)
static int get_event_first_active (void)
static int convert_libpfm4_to_string (int code, char **event_name)
static int convert_pfmidx_to_native (int code, unsigned int *PapiEventCode)
static int find_next_umask (struct native_event_t *current_event, int current, char *umask_name)
int _papi_libpfm4_error (int pfm_error)
int _papi_libpfm4_ntv_name_to_code (char *name, unsigned int *event_code)
int _papi_libpfm4_ntv_code_to_name (unsigned int EventCode, char *ntv_name, int len)
int _papi_libpfm4_ntv_code_to_descr (unsigned int EventCode, char *ntv_descr, int len)
int _papi_libpfm4_ntv_code_to_info (unsigned int EventCode, PAPI_event_info_t *info)
int _papi_libpfm4_ntv_enum_events (unsigned int *PapiEventCode, int modifier)
int _papi_libpfm4_shutdown (void)
int _papi_libpfm4_init (papi_vector_t *my_vector, int cidx)
int _papi_libpfm4_setup_counters (struct perf_event_attr *attr, int event)

Variables

static struct native_event_tnative_events
static int num_native_events = 0
static int allocated_native_events = 0
static pfm_pmu_info_t default_pmu

Define Documentation

#define NATIVE_EVENT_CHUNK   1024

Definition at line 18 of file papi_libpfm4_events.c.


Function Documentation

int _papi_libpfm4_error ( int  pfm_error)

< No error

< Not supported

< Invalid argument

< PAPI hasn't been initialized yet

< Event does not exist

< Bad combination of features

< Invalid or missing event attributes

< Insufficient memory

< Invalid or missing event attributes

< Invalid or missing event attributes

< Invalid or missing event attributes

< Too many events or attributes

< Too many events or attributes

< Invalid argument

Definition at line 732 of file papi_libpfm4_events.c.

                                     {

  switch ( pfm_error ) {
  case PFM_SUCCESS:      return PAPI_OK;       /* success */
  case PFM_ERR_NOTSUPP:  return PAPI_ENOSUPP;  /* function not supported */
  case PFM_ERR_INVAL:    return PAPI_EINVAL;   /* invalid parameters */
  case PFM_ERR_NOINIT:   return PAPI_ENOINIT;  /* library not initialized */
  case PFM_ERR_NOTFOUND: return PAPI_ENOEVNT;  /* event not found */
  case PFM_ERR_FEATCOMB: return PAPI_ECOMBO;   /* invalid combination of features */
  case PFM_ERR_UMASK:    return PAPI_EATTR;    /* invalid or missing unit mask */
  case PFM_ERR_NOMEM:    return PAPI_ENOMEM;   /* out of memory */
  case PFM_ERR_ATTR:     return PAPI_EATTR;    /* invalid event attribute */
  case PFM_ERR_ATTR_VAL: return PAPI_EATTR;    /* invalid event attribute value */
  case PFM_ERR_ATTR_SET: return PAPI_EATTR;    /* attribute value already set */
  case PFM_ERR_TOOMANY:  return PAPI_ECOUNT;   /* too many parameters */
  case PFM_ERR_TOOSMALL: return PAPI_ECOUNT;   /* parameter is too small */
  default: return PAPI_EINVAL;
  }
}

Here is the caller graph for this function:

int _papi_libpfm4_init ( papi_vector_t my_vector,
int  cidx 
)

< A System/C library call failed

< A System/C library call failed

< A System/C library call failed

< Insufficient memory

< Not supported by component

< Not supported by component

< No error

Definition at line 1294 of file papi_libpfm4_events.c.

                                                       {

   int detected_pmus=0, found_default=0;
   int i, version;
   pfm_err_t retval;
   unsigned int ncnt;
   pfm_pmu_info_t pinfo;

   /* The following checks the version of the PFM library
      against the version PAPI linked to... */
   if ( ( retval = pfm_initialize(  ) ) != PFM_SUCCESS ) {
      PAPIERROR( "pfm_initialize(): %s", pfm_strerror( retval ) );
      return PAPI_ESYS;
   }

   /* get the libpfm4 version */
   SUBDBG( "pfm_get_version()\n");
   if ( (version=pfm_get_version( )) < 0 ) {
      PAPIERROR( "pfm_get_version(): %s", pfm_strerror( retval ) );
      return PAPI_ESYS;
   }

   /* Set the version */
   sprintf( my_vector->cmp_info.support_version, "%d.%d",
        PFM_MAJ_VERSION( version ), PFM_MIN_VERSION( version ) );

   /* Complain if the compiled-against version doesn't match current version */
   if ( PFM_MAJ_VERSION( version ) != PFM_MAJ_VERSION( LIBPFM_VERSION ) ) {
      PAPIERROR( "Version mismatch of libpfm: compiled %x vs. installed %x\n",
                   PFM_MAJ_VERSION( LIBPFM_VERSION ),
                   PFM_MAJ_VERSION( version ) );
      return PAPI_ESYS;
   }

   /* allocate the native event structure */

   num_native_events=0;

   native_events=calloc(NATIVE_EVENT_CHUNK,sizeof(struct native_event_t));
   if (native_events==NULL) {
      return PAPI_ENOMEM;
   }
   allocated_native_events=NATIVE_EVENT_CHUNK;

   /* Count number of present PMUs */
   detected_pmus=0;
   ncnt=0;

   /* need to init pinfo or pfmlib might complain */
   memset(&default_pmu, 0, sizeof(pfm_pmu_info_t));
   /* init default pmu */
   retval=pfm_get_pmu_info(0, &default_pmu);
   
   SUBDBG("Detected pmus:\n");
   for(i=0;i<PFM_PMU_MAX;i++) {
      memset(&pinfo,0,sizeof(pfm_pmu_info_t));
      retval=pfm_get_pmu_info(i, &pinfo);
      if (retval!=PFM_SUCCESS) {
     continue;
      }
      if (pinfo.is_present) {
     SUBDBG("\t%d %s %s %d\n",i,pinfo.name,pinfo.desc,pinfo.type);

         detected_pmus++;
     ncnt+=pinfo.nevents;

     /* Choose default PMU */
     if ( (pinfo.type==PFM_PMU_TYPE_CORE) &&
              strcmp(pinfo.name,"ix86arch")) {

        SUBDBG("\t  %s is default\n",pinfo.name);
        memcpy(&default_pmu,&pinfo,sizeof(pfm_pmu_info_t));
        found_default++;
     }
      }
   }
   SUBDBG("%d native events detected on %d pmus\n",ncnt,detected_pmus);

   if (!found_default) {
      PAPIERROR("Could not find default PMU\n");
      return PAPI_ECMP;
   }

   if (found_default>1) {
     PAPIERROR("Found too many default PMUs!\n");
     return PAPI_ECMP;
   }

   my_vector->cmp_info.num_native_events = ncnt;

   my_vector->cmp_info.num_cntrs = default_pmu.num_cntrs+
                                  default_pmu.num_fixed_cntrs;

   SUBDBG( "num_counters: %d\n", my_vector->cmp_info.num_cntrs );
   
   /* Setup presets */
   retval = _papi_load_preset_table( (char *)default_pmu.name, 
                    default_pmu.pmu, cidx );
   if ( retval ) {
      return retval;
   }    

   return PAPI_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_libpfm4_ntv_code_to_descr ( unsigned int  EventCode,
char *  ntv_descr,
int  len 
)

< Event does not exist

< Insufficient memory

< Invalid or missing event attributes

< Buffer size exceeded

< No error

Definition at line 871 of file papi_libpfm4_events.c.

{
  int ret,a,first_mask=1;
  char *eventd, *tmp=NULL;
  pfm_event_info_t gete;

  pfm_event_attr_info_t ainfo;
  char *b;
  char event_string[BUFSIZ],*ptr;
  char temp_string[BUFSIZ];

  struct native_event_t *our_event;

  SUBDBG("ENTER %x\n",EventCode);

  our_event=find_existing_event_by_number(EventCode);
  if (our_event==NULL) {
     return PAPI_ENOEVNT;
  }

  SUBDBG("Getting info on %x\n",our_event->libpfm4_idx);
    
  /* libpfm requires the structure be zeroed */
  memset( &gete, 0, sizeof ( gete ) );

  ret=pfm_get_event_info(our_event->libpfm4_idx, PFM_OS_PERF_EVENT, &gete);
  if (ret<0) {
     SUBDBG("Return=%d\n",ret);
     return _papi_libpfm4_error(ret);
  }

  eventd=strdup(gete.desc);

  tmp = ( char * ) malloc( strlen( eventd ) + 1 );
  if ( tmp == NULL ) {
     free( eventd );
     return PAPI_ENOMEM;
  }
    
  tmp[0] = '\0';
  strcat( tmp, eventd );
  free( eventd );
    
  /* Handle Umasks */

  /* attributes concactinated onto end of descr separated by ", masks" */
  /* then comma separated */

  strcpy(event_string,our_event->allocated_name);

  /* Point to first umask */

  /* Skip the pmu name :: if one exists */
  if (strstr(event_string,"::")) {
     ptr=strstr(event_string,"::");
     ptr+=2;
     b=strtok(ptr,":");
  }
  else {
     b=strtok(event_string,":");
  }
  
  /* if no umask, then done */
  if (!b) {
     SUBDBG("No colon!\n"); /* no umask */
     goto descr_in_tmp;
  }

  /* skip first */
  b=strtok(NULL,":");
  if (!b) {
     SUBDBG("Skipping first failed\n");
     goto descr_in_tmp;
  }

  /* loop through all umasks, seeing which match */
  while(b) {
    a=0;
    while(1) {

      SUBDBG("get_event_attr %x %p\n",our_event->libpfm4_idx,&ainfo);

      memset(&ainfo,0,sizeof(pfm_event_attr_info_t));

      ret = pfm_get_event_attr_info(our_event->libpfm4_idx, a, 
                    PFM_OS_PERF_EVENT, &ainfo);
      if (ret != PFM_SUCCESS) {
    SUBDBG("get_event_attr failed %s\n",pfm_strerror(ret));
    return _papi_libpfm4_error(ret);
      }

      /* Plain UMASK case */
      if (ainfo.type == PFM_ATTR_UMASK) {
   
         SUBDBG("Trying %s with %s\n",ainfo.name,b);

         if (!strcasecmp(ainfo.name, b)) {
        int new_length;

        SUBDBG("Found %s\n",b);
        new_length=strlen(ainfo.desc);

        if (first_mask) {
           tmp=realloc(tmp,strlen(tmp)+new_length+1+strlen(", masks:"));
           strcat(tmp,", masks:");
           first_mask=0;
        }
        else {
           tmp=realloc(tmp,strlen(tmp)+new_length+1+strlen(","));
           strcat(tmp,",");
        }
        strcat(tmp,ainfo.desc);

        goto found_attr;
     }
      }

      /* Boolean Case */
      if (ainfo.type == PFM_ATTR_MOD_BOOL) {
    
     sprintf(temp_string,"%s=0",ainfo.name);

         SUBDBG("Trying %s with %s\n",temp_string,b);

         if (!strcasecmp(temp_string, b)) {
        int new_length;

        SUBDBG("Found %s\n",b);
        new_length=strlen(ainfo.desc);

        if (first_mask) {
           tmp=realloc(tmp,strlen(tmp)+new_length+1+strlen(", masks:"));
           strcat(tmp,", masks:");
           first_mask=0;
        }
        else {
           tmp=realloc(tmp,strlen(tmp)+new_length+1+strlen(","));
           strcat(tmp,",");
        }
        strcat(tmp,ainfo.desc);

        goto found_attr;
     }
      }

      /* Integer Case */
      if (ainfo.type == PFM_ATTR_MOD_INTEGER) {

     sprintf(temp_string,"%s=0",ainfo.name);

         SUBDBG("Trying %s with %s\n",temp_string,b);

         if (!strcasecmp(temp_string, b)) {
        int new_length;

        SUBDBG("Found %s\n",b);
        new_length=strlen(ainfo.desc);

        if (first_mask) {
           tmp=realloc(tmp,strlen(tmp)+new_length+1+strlen(", masks:"));
           strcat(tmp,", masks:");
           first_mask=0;
        }
        else {
           tmp=realloc(tmp,strlen(tmp)+new_length+1+strlen(","));
           strcat(tmp,",");
        }
        strcat(tmp,ainfo.desc);

        goto found_attr;
     }
      }

      a++;
    }

    SUBDBG("attr=%s not found for event %s\n", b, ainfo.name);

    return PAPI_EATTR;

found_attr:

    b=strtok(NULL,":");
  }

  /* We are done and the description to copy is in tmp */
descr_in_tmp:
    strncpy( ntv_descr, tmp, ( size_t ) len );
    if ( ( int ) strlen( tmp ) > len - 1 )
        ret = PAPI_EBUF;
    else
        ret = PAPI_OK;
    free( tmp );

    SUBDBG("PFM4 Code: %x %s\n",EventCode,ntv_descr);

    return ret;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_libpfm4_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
)

< Event does not exist

< Buffer size exceeded

< No error

Definition at line 1073 of file papi_libpfm4_events.c.

{


  struct native_event_t *our_event;

  SUBDBG("ENTER %x\n",EventCode);

  our_event=find_existing_event_by_number(EventCode);
  if (our_event==NULL) {
     return PAPI_ENOEVNT;
  }

  strncpy(info->symbol, our_event->allocated_name, sizeof(info->symbol));

  if (strlen(our_event->allocated_name) > sizeof(info->symbol)) {
     return PAPI_EBUF;
  }

  _papi_libpfm4_ntv_code_to_descr(EventCode,info->long_descr,
                 sizeof(info->long_descr));

  return PAPI_OK;
}

Here is the call graph for this function:

int _papi_libpfm4_ntv_code_to_name ( unsigned int  EventCode,
char *  ntv_name,
int  len 
)

< Event does not exist

< Buffer size exceeded

< No error

Definition at line 828 of file papi_libpfm4_events.c.

{

        struct native_event_t *our_event;

        SUBDBG("ENTER %x\n",EventCode);

        our_event=find_existing_event_by_number(EventCode);
    if (our_event==NULL) {
      return PAPI_ENOEVNT;
    }

    strncpy(ntv_name,our_event->allocated_name,len);

    if (strlen(our_event->allocated_name) > (unsigned)len) {
       return PAPI_EBUF;
    }

    return PAPI_OK;
}

Here is the call graph for this function:

int _papi_libpfm4_ntv_enum_events ( unsigned int *  PapiEventCode,
int  modifier 
)

< Event does not exist

< Not implemented

< No error

< Event does not exist

< No error

< Not implemented

Definition at line 1115 of file papi_libpfm4_events.c.

{
    int code,ret;
    struct native_event_t *current_event;

        SUBDBG("ENTER\n");

    /* return first event if so specified */
    if ( modifier == PAPI_ENUM_FIRST ) {

       unsigned int papi_event=0;

           SUBDBG("ENUM_FIRST\n");

       code=get_event_first_active();
       SUBDBG("ENUM_FIRST code: %d\n",code);
       if (code < 0 ) {
          return code;
       }

       /* convert the libpfm4 event to a PAPI event */
       ret=convert_pfmidx_to_native(code, &papi_event);

       *PapiEventCode=(unsigned int)papi_event;

           SUBDBG("FOUND %x (from %x) ret=%d\n",*PapiEventCode,code,ret);

       return ret;
    }

    /* If we get this far, we're looking for a        */
    /* next-event.  So gather info on the current one */
    current_event=find_existing_event_by_number(*PapiEventCode);
    if (current_event==NULL) {
           SUBDBG("EVENTS %x not found\n",*PapiEventCode);
       return PAPI_ENOEVNT;
    }


    /* Handle looking for the next event */

    if ( modifier == PAPI_ENUM_EVENTS ) {

       unsigned int papi_event=0;

       SUBDBG("PAPI_ENUM_EVENTS %x\n",*PapiEventCode);

       code=current_event->libpfm4_idx;

       ret=find_next_no_aliases(code);
       SUBDBG("find_next_no_aliases() Returned %x\n",ret);
       if (ret<0) {
          return ret;
       }

       /* Convert libpfm4 event code to PAPI event code */
       ret=convert_pfmidx_to_native(ret, &papi_event);
       if (ret<0) {
           SUBDBG("Couldn't convert to native %d %s\n",
              ret,PAPI_strerror(ret));
           return ret;
       }

       *PapiEventCode=(unsigned int)papi_event;

           SUBDBG("Returning PAPI_OK\n");

       return ret;
    }

    /* We don't handle PAPI_NTV_ENUM_UMASK_COMBOS */
    if ( modifier == PAPI_NTV_ENUM_UMASK_COMBOS ) {
       return PAPI_ENOIMPL;
    } 

    /* Enumerate PAPI_NTV_ENUM_UMASKS (umasks on an event) */
    if ( modifier == PAPI_NTV_ENUM_UMASKS ) {

       int max_umask,next_umask;
       char umask_string[BUFSIZ],new_name[BUFSIZ];

       SUBDBG("Finding maximum mask in event %s\n",
                  current_event->allocated_name);

       max_umask=find_max_umask(current_event);
       SUBDBG("Found max %d\n",max_umask);

       if (max_umask<0) {
          if (max_umask==PFM_ERR_UMASK) {
             max_umask=-1; /* needed for find_next_umask() to work */
                       /* indicates the event as passed had no */
                       /* umask in it.                         */
          }
          else {
             return _papi_libpfm4_error(max_umask);
          }
       }

       next_umask=find_next_umask(current_event,max_umask,
                      umask_string);

       SUBDBG("Found next %d\n",next_umask);

       if (next_umask>=0) {

          unsigned int papi_event;

          sprintf(new_name,"%s:%s",current_event->base_name,
             umask_string);
     
          SUBDBG("Found new name %s\n",new_name);

              ret=_papi_libpfm4_ntv_name_to_code(new_name,&papi_event);
          if (ret!=PAPI_OK) {
         return PAPI_ENOEVNT;
          }

          *PapiEventCode=(unsigned int)papi_event;
          SUBDBG("found code %x\n",*PapiEventCode);

          return PAPI_OK;
       }

       SUBDBG("couldn't find umask\n");

       return _papi_libpfm4_error(next_umask);

    }
    
    /* An unknown enumeration method was indicated */

    return PAPI_ENOIMPL;
}

Here is the call graph for this function:

int _papi_libpfm4_ntv_name_to_code ( char *  name,
unsigned int *  event_code 
)

< Event does not exist

< No error

< Event does not exist

Definition at line 765 of file papi_libpfm4_events.c.

{

  int actual_idx;
  struct native_event_t *our_event;
  int event_num;

  SUBDBG( "Converting %s\n", name);

  event_num=find_existing_event(name);

  if (event_num<0) {

     /* event currently doesn't exist, so try to find it */
     /* using libpfm4                                    */

     SUBDBG("Using pfm to look up event %s\n",name);
     actual_idx=pfm_find_event(name);
     if (actual_idx<0) {
        return _papi_libpfm4_error(actual_idx);
     }

     SUBDBG("Using %x as the index\n",actual_idx);

     /* We were found in libpfm4, so allocate our copy of the event */

     our_event=allocate_native_event(name,actual_idx);
     if (our_event==NULL) return PAPI_ENOEVNT;

     event_num=find_existing_event(name);
  }

  if (event_num>=0) {      
     *event_code=event_num;
     SUBDBG("Found code: %x\n",*event_code);
     return PAPI_OK;
  }

  /* Failure here means allocate_native_event failed */

  SUBDBG("Event %s not found\n",name);

  return PAPI_ENOEVNT;   

}

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_libpfm4_setup_counters ( struct perf_event_attr attr,
int  event 
)

< Event does not exist

< No error

Definition at line 1413 of file papi_libpfm4_events.c.

                             {

  struct native_event_t *our_event;

  our_event=find_existing_event_by_number(event);
  if (our_event==NULL) {
     return PAPI_ENOEVNT;
  }

  attr->config=our_event->config; 
  attr->config1=our_event->config1;
  attr->config2=our_event->config2;
  attr->type=our_event->type;
  
  SUBDBG( "pe_event: config 0x%"PRIx64
          " config1 0x%"PRIx64
          " type 0x%"PRIx32"\n", 
          attr->config, 
      attr->config1,
      attr->type);
      

  return PAPI_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:

int _papi_libpfm4_shutdown ( void  )

< Used with setting up array

< Used with setting up array

< No error

Definition at line 1257 of file papi_libpfm4_events.c.

                             {

  int i;

  SUBDBG("shutdown\n");

  /* clean out and free the native events structure */
  _papi_hwi_lock( NAMELIB_LOCK );

  /* free memory allocate with strdup */
  for( i=0; i<num_native_events; i++) {
     free(native_events[i].base_name);
     free(native_events[i].pmu_plus_name);
     free(native_events[i].pmu);
     free(native_events[i].allocated_name);
  }

  memset(native_events,0,
     sizeof(struct native_event_t)*allocated_native_events);
  num_native_events=0;
  allocated_native_events=0;
  free(native_events);
  _papi_hwi_unlock( NAMELIB_LOCK );

  return PAPI_OK;
}

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  event_idx 
) [static, read]

< Used with setting up array

< Used with setting up array

Definition at line 229 of file papi_libpfm4_events.c.

                                           {

  int new_event;

  pfm_err_t ret;
  unsigned int i;
  char *base_start;
  pfm_event_info_t info;
  pfm_pmu_info_t pinfo;
  char base[BUFSIZ],pmuplusbase[BUFSIZ];
  char fullname[BUFSIZ];

  pfm_perf_encode_arg_t perf_arg;

  struct perf_event_attr perf_attr;

  /* get the event name from libpfm */
  memset(&info,0,sizeof(pfm_event_info_t));
  ret = pfm_get_event_info(event_idx, PFM_OS_PERF_EVENT, &info);
  if (ret!=PFM_SUCCESS) {
     return NULL;
  }

  /* get the PMU info */
  memset(&pinfo,0,sizeof(pfm_pmu_info_t));
  pfm_get_pmu_info(info.pmu, &pinfo);

  /* calculate the base name, meaning strip off pmu identifier */
  strncpy(base,name,BUFSIZ);
  i=0;
  base_start=base;
  while(i<strlen(base)) {
    if (base[i]==':') {
      if (base[i+1]==':') {
          i++;
      base_start=&base[i+1];
      }
      else {
    base[i]=0;
      }
    }
    i++;
  }

  /* add the event */
  _papi_hwi_lock( NAMELIB_LOCK );

  new_event=num_native_events;

  native_events[new_event].base_name=strdup(base_start);

  sprintf(fullname,"%s::%s",pinfo.name,info.name);
  native_events[new_event].pmu_plus_name=strdup(fullname);

  sprintf(pmuplusbase,"%s::%s",pinfo.name,base_start);

  native_events[new_event].component=0;
  native_events[new_event].pmu=strdup(pinfo.name);
    
  native_events[new_event].libpfm4_idx=find_event_no_aliases(pmuplusbase);

  SUBDBG("Using %x as index instead of %x for %s\n",
     native_events[new_event].libpfm4_idx,event_idx,pmuplusbase);

  native_events[new_event].allocated_name=strdup(name);

  /* is this needed? */
  native_events[new_event].users=0;


  /* use name of the event to get the perf_event encoding */

  /* clear the attribute structure */
  memset(&perf_arg,0,sizeof(pfm_perf_encode_arg_t));

  /* clear out the perf_attr struct */
  memset(&perf_attr,0,sizeof(struct perf_event_attr));
  perf_arg.attr=&perf_attr;

  ret = pfm_get_os_event_encoding(name, 
                  PFM_PLM0 | PFM_PLM3, 
                                  PFM_OS_PERF_EVENT, 
                  &perf_arg);
  if (ret!=PFM_SUCCESS) {
     /* should do something! */
  }
  
  native_events[new_event].config=perf_arg.attr->config;
  native_events[new_event].config1=perf_arg.attr->config1;
  native_events[new_event].type=perf_arg.attr->type;

  SUBDBG( "pe_event: config 0x%"PRIx64" config1 0x%"PRIx64" type 0x%"PRIx32"\n", 
          perf_arg.attr->config, 
      perf_arg.attr->config1,
      perf_arg.attr->type);

  SUBDBG("Creating event %s with perfidx %x\n",
     name,
     native_events[new_event].libpfm4_idx);

  num_native_events++;

  /* If we've allocated too many native events, then allocate more room */
  if (num_native_events >= allocated_native_events) {

     SUBDBG("Allocating more room for native events (%d %ld)\n",
        (allocated_native_events+NATIVE_EVENT_CHUNK),
        (long)sizeof(struct native_event_t) *
        (allocated_native_events+NATIVE_EVENT_CHUNK));

     native_events=realloc(native_events,
               sizeof(struct native_event_t) * 
               (allocated_native_events+NATIVE_EVENT_CHUNK));
     allocated_native_events+=NATIVE_EVENT_CHUNK;
  }

  _papi_hwi_unlock( NAMELIB_LOCK );

  if (native_events==NULL) {
     return NULL;
  }

  return &native_events[new_event];

}

Here is the call graph for this function:

Here is the caller graph for this function:

static int convert_libpfm4_to_string ( int  code,
char **  event_name 
) [static]

Definition at line 538 of file papi_libpfm4_events.c.

{

  int ret;
  pfm_event_info_t gete;
  pfm_pmu_info_t pinfo;
  char name[BUFSIZ];

  SUBDBG("ENTER %x\n",code);

  /* Clear structures, as wanted by libpfm4 */
  memset( &gete, 0, sizeof (pfm_event_info_t) );

  ret=pfm_get_event_info(code, PFM_OS_PERF_EVENT, &gete);
  if (ret!=PFM_SUCCESS) {
     return ret;
  }

  memset( &pinfo, 0, sizeof(pfm_pmu_info_t) );
  ret=pfm_get_pmu_info(gete.pmu, &pinfo);
  if (ret!=PFM_SUCCESS) {
     return ret;
  }

  /* Only prepend PMU name if not on the "default" PMU */

  if (pinfo.pmu == default_pmu.pmu) {
     *event_name=strdup(gete.name);
  }
  else {
     sprintf(name,"%s::%s",pinfo.name,gete.name);
     *event_name=strdup(name);
  }

  SUBDBG("Found name: %s\n",*event_name);

  return PFM_SUCCESS;

}

Here is the caller graph for this function:

static int convert_pfmidx_to_native ( int  code,
unsigned int *  PapiEventCode 
) [static]

Definition at line 591 of file papi_libpfm4_events.c.

                                                                           {

  int ret;
  char *name=NULL;

  ret=convert_libpfm4_to_string( code, &name);
  if (ret!=PFM_SUCCESS) {
     return _papi_libpfm4_error(ret);
  }

  SUBDBG("Converted %x to %s\n",code,name);

  ret=_papi_libpfm4_ntv_name_to_code(name,PapiEventCode);

  SUBDBG("Converted %s to event %x\n",name,*PapiEventCode);

  if (name) free(name);

  return ret;

}

Here is the call graph for this function:

Here is the caller graph for this function:

static int find_event_no_aliases ( char *  name) [static]

Definition at line 113 of file papi_libpfm4_events.c.

                                             {

    int j,i, ret;
    pfm_pmu_info_t pinfo;
    pfm_event_info_t event_info;
    char full_name[BUFSIZ];

    SUBDBG("Looking for %s\n",name);

    pfm_for_all_pmus(j) {

       memset(&pinfo,0,sizeof(pfm_pmu_info_t));
       pfm_get_pmu_info(j, &pinfo);
       if (!pinfo.is_present) {
          continue;
       }

       SUBDBG("Looking in pmu %d\n",j);   
       i = pinfo.first_event; 
       while(1) {
          memset(&event_info,0,sizeof(pfm_event_info_t));
          ret=pfm_get_event_info(i, PFM_OS_PERF_EVENT, &event_info);
      if (ret<0) break;
    
      sprintf(full_name,"%s::%s",pinfo.name,event_info.name);

      if (!strcmp(name,full_name)) {
         SUBDBG("FOUND %s %s %x\n",name,full_name,i);
         return i;
      }

      if (!strcmp(name,event_info.name)) {
         SUBDBG("FOUND %s %s %x\n",name,event_info.name,i);
         return i;
      }
      i=pfm_get_event_next(i);
       }
    }
    return PFM_ERR_NOTFOUND;
}

Here is the caller graph for this function:

static int find_existing_event ( char *  name) [static]

< Event does not exist

< Used with setting up array

< Used with setting up array

Definition at line 52 of file papi_libpfm4_events.c.

                                           {

  int i,event=PAPI_ENOEVNT;

  SUBDBG("Looking for %s in %d events\n",name,num_native_events);

  _papi_hwi_lock( NAMELIB_LOCK );

  for(i=0;i<num_native_events;i++) {

    if (!strcmp(name,native_events[i].allocated_name)) {
      SUBDBG("Found %s (%x)\n",
         native_events[i].allocated_name,
         native_events[i].libpfm4_idx);
      event=i;
      break;
    }
  }
  _papi_hwi_unlock( NAMELIB_LOCK );

  if (event<0) { SUBDBG("%s not allocated yet\n",name); }

  return event;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct native_event_t* find_existing_event_by_number ( int  eventnum) [static, read]

< Used with setting up array

< Used with setting up array

Definition at line 87 of file papi_libpfm4_events.c.

                                                                          {

  struct native_event_t *temp_event=NULL;

  _papi_hwi_lock( NAMELIB_LOCK );

  temp_event=&native_events[eventnum];
  
  _papi_hwi_unlock( NAMELIB_LOCK );

  SUBDBG("Found %p for %x\n",temp_event,eventnum);

  return temp_event;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int find_max_umask ( struct native_event_t current_event) [static]

Definition at line 370 of file papi_libpfm4_events.c.

                                                                {

  pfm_event_attr_info_t ainfo;
  char *b;
  int a, ret, max =0;
  pfm_event_info_t info;
  char event_string[BUFSIZ],*ptr;
  char temp_string[BUFSIZ];

  SUBDBG("Trying to find max umask in %s\n",current_event->allocated_name);

  strcpy(event_string,current_event->allocated_name);

  /* Skip leading :: delimited PMU name and point to first umask */
  if (strstr(event_string,"::")) {
     ptr=strstr(event_string,"::");
     ptr+=2;
     b=strtok(ptr,":");
  }
  else {
     b=strtok(event_string,":");
  }

  if (!b) {
     SUBDBG("No colon!\n");
     return PFM_ERR_UMASK; /* Must be this value!! */
  }

  memset(&info,0,sizeof(pfm_event_info_t));
  ret = pfm_get_event_info(current_event->libpfm4_idx, 
               PFM_OS_PERF_EVENT, &info);
  if (ret!=PFM_SUCCESS) {
     SUBDBG("get_event_info failed\n");
     return PFM_ERR_NOTFOUND;
  }

  /* skip first */
  b=strtok(NULL,":");
  if (!b) {
     SUBDBG("Skipping first failed\n");
     return PFM_ERR_UMASK; /* Must be this value!! */
  }

  while(b) {
    a=0;
    while(1) {

      SUBDBG("get_event_attr %x %d %p\n",current_event->libpfm4_idx,a,&ainfo);

      memset(&ainfo,0,sizeof(pfm_event_attr_info_t));

      ret = pfm_get_event_attr_info(current_event->libpfm4_idx, a, 
                    PFM_OS_PERF_EVENT, &ainfo);

      if (ret != PFM_SUCCESS) {
    SUBDBG("get_event_attr failed %s\n",pfm_strerror(ret));
    return ret;
      }

      SUBDBG("Trying %s with %s\n",ainfo.name,b);

      if (ainfo.type == PFM_ATTR_MOD_BOOL) {
     sprintf(temp_string,"%s=0",ainfo.name);
         if (!strcasecmp(temp_string, b)) {
        SUBDBG("Found %s %d\n",b,a);
        if (a>max) max=a;
        goto found_attr;
     }
      }
      else if (ainfo.type == PFM_ATTR_MOD_INTEGER) {
     sprintf(temp_string,"%s=0",ainfo.name);
         if (!strcasecmp(temp_string, b)) {
        SUBDBG("Found %s %d\n",b,a);
        if (a>max) max=a;
        goto found_attr;
     }
      }
      else {
         if (!strcasecmp(ainfo.name, b)) {
        SUBDBG("Found %s %d\n",b,a);
        if (a>max) max=a;
        goto found_attr;
     }
      }
      a++;
    }

    SUBDBG("attr=%s not found for event %s\n", b, info.name);

    return PFM_ERR_ATTR;

found_attr:

    b=strtok(NULL,":");
  }

  SUBDBG("Found max %d\n", max);

  return max;
}

Here is the caller graph for this function:

static int find_next_no_aliases ( int  code) [static]

Definition at line 165 of file papi_libpfm4_events.c.

                                          {

  int current_pmu=0,current_event=0;
  pfm_err_t ret;
  pfm_pmu_info_t pinfo;
  pfm_event_info_t event_info;

  /* Clear the structures, as libpfm4 requires it */
  memset(&event_info,0,sizeof(pfm_event_info_t));

  ret=pfm_get_event_info(code, PFM_OS_PERF_EVENT, &event_info);
  if (ret!=PFM_SUCCESS) {
     return ret;
  }

  current_pmu=event_info.pmu;
  current_event=pfm_get_event_next(code);

  SUBDBG("Current is %x guessing next is %x\n",code,current_event);

  while(1) {

     memset(&event_info,0,sizeof(pfm_event_info_t));
     ret=pfm_get_event_info(current_event, PFM_OS_PERF_EVENT, &event_info);
     if (ret==PFM_SUCCESS) {
        SUBDBG("Returning %x\n",current_event);
        return current_event;
     }

     /* next event not found, so try moving to next PMU */

     while(1) {

        current_pmu++;
        SUBDBG("Incrementing PMU: %x\n",current_pmu);

    /* Off the end, so done iterating */
        if (current_pmu>PFM_PMU_MAX) {
           return PFM_ERR_NOTFOUND;
        }
 
        memset(&pinfo,0,sizeof(pfm_pmu_info_t));
        pfm_get_pmu_info(current_pmu, &pinfo);
        if (pinfo.is_present) break;
     }

     current_event=pinfo.first_event;

  }

}

Here is the caller graph for this function:

static int find_next_umask ( struct native_event_t current_event,
int  current,
char *  umask_name 
) [static]

Definition at line 632 of file papi_libpfm4_events.c.

                                                         {

  char temp_string[BUFSIZ];
  pfm_event_info_t event_info;
  pfm_event_attr_info_t ainfo;
  int num_masks=0;
  pfm_err_t ret;
  int i;

  /* get number of attributes */

  memset(&event_info, 0, sizeof(event_info));
  ret=pfm_get_event_info(current_event->libpfm4_idx, 
             PFM_OS_PERF_EVENT, &event_info);
  if (ret!=PFM_SUCCESS) {
     return ret;
  }
    
  SUBDBG("%d possible attributes for event %s\n",
     event_info.nattrs,
     event_info.name);

  pfm_for_each_event_attr(i, &event_info) {

     ainfo.size = sizeof(ainfo);

     ret = pfm_get_event_attr_info(event_info.idx, i, PFM_OS_PERF_EVENT, 
                   &ainfo);
     if (ret != PFM_SUCCESS) {
        SUBDBG("Not found\n");
    return PFM_ERR_NOTFOUND;
     }

     if (ainfo.type == PFM_ATTR_UMASK) {
    SUBDBG("nm %d looking for %d\n",num_masks,current);
    if (num_masks==current+1) {   
       SUBDBG("Found attribute %d: %s type: %d\n",
          i,ainfo.name,ainfo.type);
    
           sprintf(temp_string,"%s",ainfo.name);
           strncpy(umask_name,temp_string,BUFSIZ);

       return current+1;
    }
    num_masks++;
     }

     if (ainfo.type == PFM_ATTR_MOD_BOOL) {
    SUBDBG("nm %d looking for %d\n",num_masks,current);
    
    if (num_masks==current+1) {   
       SUBDBG("Found attribute %d: %s type: %d\n",
          i,ainfo.name,ainfo.type);
    
           sprintf(temp_string,"%s=0",ainfo.name);
           strncpy(umask_name,temp_string,BUFSIZ);

       return current+1;
    }
    num_masks++;
     }

     if (ainfo.type == PFM_ATTR_MOD_INTEGER) {
    SUBDBG("nm %d looking for %d\n",num_masks,current);
    if (num_masks==current+1) {   
       SUBDBG("Found attribute %d: %s type: %d\n",
          i,ainfo.name,ainfo.type);
    
           sprintf(temp_string,"%s=0",ainfo.name);
           strncpy(umask_name,temp_string,BUFSIZ);

       return current+1;
    }
    num_masks++;
     }
  }

  return PFM_ERR_ATTR;

}

Here is the caller graph for this function:

static int get_event_first_active ( void  ) [static]

< Event does not exist

Definition at line 482 of file papi_libpfm4_events.c.

{
  int pidx, pmu_idx, ret;

  pfm_pmu_info_t pinfo;

  pmu_idx=0;

  while(pmu_idx<PFM_PMU_MAX) {

    /* clear the PMU structure (required by libpfm4) */
    memset(&pinfo,0,sizeof(pfm_pmu_info_t));
    ret=pfm_get_pmu_info(pmu_idx, &pinfo);

    if ((ret==PFM_SUCCESS) && pinfo.is_present) {

      pidx=pinfo.first_event;

      SUBDBG("First event in %s is %d\n",pinfo.name,pidx);

      if (pidx<0) {
    /* For some reason no events available */
    /* despite the PMU being active.       */
        /* This can happen, for example with ix86arch */
    /* inside of VMware                           */
      }
      else {
         return pidx;
      }
    }

    pmu_idx++;

  }

  return PAPI_ENOEVNT;
  
}

Here is the caller graph for this function:


Variable Documentation

int allocated_native_events = 0 [static]

Definition at line 37 of file papi_libpfm4_events.c.

pfm_pmu_info_t default_pmu [static]

Definition at line 39 of file papi_libpfm4_events.c.

struct native_event_t* native_events [static]

Definition at line 34 of file papi_libpfm4_events.c.

int num_native_events = 0 [static]

Definition at line 36 of file papi_libpfm4_events.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines