PAPI  5.0.1.0
linux-coretemp.c File Reference
Include dependency graph for linux-coretemp.c:

Go to the source code of this file.

Data Structures

struct  temp_event

Defines

#define REFRESH_LAT   4000
#define INVALID_RESULT   -1000000L
#define NUM_PATHS   2

Functions

static int insert_in_list (char *name, char *units, char *description, char *filename)
static int generateEventList (char *base_dir)
static long long getEventValue (int index)
int _coretemp_init_thread (hwd_context_t *ctx)
int _coretemp_init_component (int cidx)
int _coretemp_init_control_state (hwd_control_state_t *ctl)
int _coretemp_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _coretemp_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
int _coretemp_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _coretemp_shutdown_thread (hwd_context_t *ctx)
int _coretemp_shutdown_component ()
int _coretemp_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int _coretemp_update_control_state (hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
int _coretemp_set_domain (hwd_control_state_t *cntl, int domain)
int _coretemp_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _coretemp_ntv_enum_events (unsigned int *EventCode, int modifier)
int _coretemp_ntv_code_to_name (unsigned int EventCode, char *name, int len)
int _coretemp_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
int _coretemp_ntv_code_to_info (unsigned int EventCode, PAPI_event_info_t *info)

Variables

papi_vector_t _coretemp_vector
static
CORETEMP_native_event_entry_t
_coretemp_native_events
static int num_events = 0
static int is_initialized = 0
static struct temp_eventroot = NULL
static struct temp_eventlast = NULL

Define Documentation

#define INVALID_RESULT   -1000000L

Definition at line 15 of file linux-coretemp.c.

#define NUM_PATHS   2
#define REFRESH_LAT   4000

Definition at line 13 of file linux-coretemp.c.


Function Documentation

int _coretemp_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
)

Definition at line 502 of file linux-coretemp.c.

{
    ( void ) ctx;
    ( void ) code;
    ( void ) option;

    return PAPI_OK;
}
int _coretemp_init_component ( int  cidx)

Definition at line 342 of file linux-coretemp.c.

{
     int i = 0;
     struct temp_event *t,*last;

     if ( is_initialized )
    return (PAPI_OK );

     is_initialized = 1;

     /* This is the prefered method, all coretemp sensors are symlinked here
      * see $(kernel_src)/Documentation/hwmon/sysfs-interface */
  
     num_events = generateEventList("/sys/class/hwmon");

     if ( num_events < 0 ) {
        strncpy(_coretemp_vector.cmp_info.disabled_reason,
        "Cannot open /sys/class/hwmon",PAPI_MAX_STR_LEN);
    return PAPI_ENOCMP;
     }

     if ( num_events == 0 ) {
        strncpy(_coretemp_vector.cmp_info.disabled_reason,
        "No coretemp events found",PAPI_MAX_STR_LEN);
    return PAPI_ENOCMP;
     }

     t = root;
  
     _coretemp_native_events = (CORETEMP_native_event_entry_t*)
          papi_calloc(sizeof(CORETEMP_native_event_entry_t),num_events);

     do {
    strncpy(_coretemp_native_events[i].name,t->name,PAPI_MAX_STR_LEN);
    strncpy(_coretemp_native_events[i].path,t->path,PATH_MAX);
    strncpy(_coretemp_native_events[i].units,t->units,PAPI_MIN_STR_LEN);
    strncpy(_coretemp_native_events[i].description,t->description,
            PAPI_MAX_STR_LEN);
    _coretemp_native_events[i].stone = 0;
    _coretemp_native_events[i].resources.selector = i + 1;
    last    = t;
    t       = t->next;
    papi_free(last);
    i++;
     } while (t != NULL);
     root = NULL;

     /* Export the total number of events available */
     _coretemp_vector.cmp_info.num_native_events = num_events;

     /* Export the component id */
     _coretemp_vector.cmp_info.CmpIdx = cidx;

     return PAPI_OK;
}

Here is the call graph for this function:

Definition at line 406 of file linux-coretemp.c.

{
    int i;

    CORETEMP_control_state_t *coretemp_ctl = (CORETEMP_control_state_t *) ctl;

    for ( i=0; i < num_events; i++ ) {
    coretemp_ctl->counts[i] = getEventValue(i);
    }

    /* Set last access time for caching results */
    coretemp_ctl->lastupdate = PAPI_get_real_usec();

    return PAPI_OK;
}

Here is the call graph for this function:

Definition at line 329 of file linux-coretemp.c.

{
  ( void ) ctx;
  return PAPI_OK;
}
int _coretemp_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 629 of file linux-coretemp.c.

{
     int index = EventCode;

     if ( index >= 0 && index < num_events ) {
    strncpy( name, _coretemp_native_events[index].description, len );
    return PAPI_OK;
     }
     return PAPI_ENOEVNT;
}
int _coretemp_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
)

Definition at line 641 of file linux-coretemp.c.

{

  int index = EventCode;

  if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;

  strncpy( info->symbol, _coretemp_native_events[index].name, 
       sizeof(info->symbol));

  strncpy( info->long_descr, _coretemp_native_events[index].description, 
       sizeof(info->long_descr));

  strncpy( info->units, _coretemp_native_events[index].units, 
       sizeof(info->units));


  return PAPI_OK;
}
int _coretemp_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 614 of file linux-coretemp.c.

{
     int index = EventCode;

     if ( index >= 0 && index < num_events ) {
    strncpy( name, _coretemp_native_events[index].name, len );
    return PAPI_OK;
     }
     return PAPI_ENOEVNT;
}
int _coretemp_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

Definition at line 575 of file linux-coretemp.c.

{

     int index;

     switch ( modifier ) {

    case PAPI_ENUM_FIRST:

       if (num_events==0) {
          return PAPI_ENOEVNT;
       }
       *EventCode = 0;

       return PAPI_OK;
        

    case PAPI_ENUM_EVENTS:
    
       index = *EventCode;

       if ( index < num_events - 1 ) {
          *EventCode = *EventCode + 1;
          return PAPI_OK;
       } else {
          return PAPI_ENOEVNT;
       }
       break;
    
    default:
        return PAPI_EINVAL;
    }
    return PAPI_EINVAL;
}
int _coretemp_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
)

Definition at line 432 of file linux-coretemp.c.

{
    (void) flags;
    (void) ctx;

    CORETEMP_control_state_t* control = (CORETEMP_control_state_t*) ctl;
    long long now = PAPI_get_real_usec();
    int i;

    /* Only read the values from the kernel if enough time has passed */
    /* since the last read.  Otherwise return cached values.          */

    if ( now - control->lastupdate > REFRESH_LAT ) {
    for ( i = 0; i < num_events; i++ ) {
       control->counts[i] = getEventValue( i );
    }
    control->lastupdate = now;
    }

    /* Pass back a pointer to our results */
    *events = control->counts;

    return PAPI_OK;
}

Here is the call graph for this function:

Definition at line 562 of file linux-coretemp.c.

{
    ( void ) ctx;
    ( void ) ctl;
    
    return PAPI_OK;
}
int _coretemp_set_domain ( hwd_control_state_t cntl,
int  domain 
)

Definition at line 540 of file linux-coretemp.c.

{
    int found = 0;
    ( void ) cntl;
    
    if ( PAPI_DOM_USER & domain )
       found = 1;

       if ( PAPI_DOM_KERNEL & domain )
        found = 1;

       if ( PAPI_DOM_OTHER & domain )
        found = 1;

       if ( !found )
        return PAPI_EINVAL;

       return PAPI_OK;
}

Definition at line 475 of file linux-coretemp.c.

{
  ( void ) ctx;
  return PAPI_OK;
}

Definition at line 423 of file linux-coretemp.c.

{
  ( void ) ctx;
  ( void ) ctl;

  return PAPI_OK;
}
int _coretemp_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

Definition at line 459 of file linux-coretemp.c.

{
    (void) ctx;
    /* read values */
    CORETEMP_control_state_t* control = (CORETEMP_control_state_t*) ctl;
    int i;

    for ( i = 0; i < num_events; i++ ) {
    control->counts[i] = getEventValue( i );
    }

    return PAPI_OK;
}

Here is the call graph for this function:

int _coretemp_update_control_state ( hwd_control_state_t ptr,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)

Definition at line 513 of file linux-coretemp.c.

{
    int i, index;
    ( void ) ctx;
    ( void ) ptr;

    for ( i = 0; i < count; i++ ) {
    index = native[i].ni_event;
    native[i].ni_position = _coretemp_native_events[index].resources.selector - 1;
    }
    return PAPI_OK;
}
static int generateEventList ( char *  base_dir) [static]

Definition at line 91 of file linux-coretemp.c.

{
    char path[PATH_MAX],filename[PATH_MAX];
    char modulename[PAPI_MIN_STR_LEN],
         location[PAPI_MIN_STR_LEN],
         units[PAPI_MIN_STR_LEN],
         description[PAPI_MAX_STR_LEN],
         name[PAPI_MAX_STR_LEN];
    DIR *dir,*d;
    FILE *fff;
    int count = 0;
    struct dirent *hwmonx;
    int i,pathnum;

#define NUM_PATHS 2
    char paths[NUM_PATHS][PATH_MAX]={
      "device","."
    };

    /* Open "/sys/class/hwmon" */
    dir = opendir(base_dir);
    if ( dir == NULL ) {
       SUBDBG("Can't find %s, are you sure the coretemp module is loaded?\n", 
           base_dir);
       return 0;
    }

    /* Iterate each /sys/class/hwmonX/device directory */
    while( (hwmonx = readdir(dir) ) ) {
       if ( !strncmp("hwmon", hwmonx->d_name, 5) ) {

     /* Found a hwmon directory */

     /* Sometimes the files are in ./, sometimes in device/ */
     for(pathnum=0;pathnum<NUM_PATHS;pathnum++) {

        snprintf(path, PATH_MAX, "%s/%s/%s", 
             base_dir, hwmonx->d_name,paths[pathnum]);

        SUBDBG("Trying to open %s\n",path);
        d = opendir(path);
        if (d==NULL) {
           continue;
        }

        /* Get the name of the module */

        snprintf(filename, PAPI_MAX_STR_LEN, "%s/name",path);
        fff=fopen(filename,"r");
        if (fff==NULL) {
           snprintf(modulename, PAPI_MIN_STR_LEN, "Unknown");
        } else {
           if (fgets(modulename,PAPI_MIN_STR_LEN,fff)!=NULL) {
              modulename[strlen(modulename)-1]='\0';
           }
           fclose(fff);
        }

        SUBDBG("Found module %s\n",modulename);

      /******************************************************/
      /* Try handling all events starting with in (voltage) */
      /******************************************************/


        /* arbitrary maximum */
        /* the problem is the numbering can be sparse */
        /* should probably go back to dirent listing  */
        
      for(i=0;i<32;i++) {

         /* Try looking for a location label */
         snprintf(filename, PAPI_MAX_STR_LEN, "%s/in%d_label", 
              path,i);
         fff=fopen(filename,"r");
         if (fff==NULL) {
            strncpy(location,"?",PAPI_MIN_STR_LEN);
         }
         else {
            if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
               location[strlen(location)-1]='\0';
            }
            fclose(fff);
         }

         /* Look for input temperature */
         snprintf(filename, PAPI_MAX_STR_LEN, "%s/in%d_input", 
              path,i);
         fff=fopen(filename,"r");
         if (fff==NULL) continue;
         fclose(fff);

         snprintf(name, PAPI_MAX_STR_LEN, "%s:in%i_input", 
             hwmonx->d_name, i);
         snprintf(units, PAPI_MIN_STR_LEN, "V");
         snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
              units,modulename,
              location);

         if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
            goto done_error;
         }

         count++;

      }

      /************************************************************/
      /* Try handling all events starting with temp (temperature) */
      /************************************************************/

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

         /* Try looking for a location label */
         snprintf(filename, PAPI_MAX_STR_LEN, "%s/temp%d_label", 
              path,i);
         fff=fopen(filename,"r");
         if (fff==NULL) {
            strncpy(location,"?",PAPI_MIN_STR_LEN);
         }
         else {
            if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
               location[strlen(location)-1]='\0';
            }
            fclose(fff);
         }

         /* Look for input temperature */
         snprintf(filename, PAPI_MAX_STR_LEN, "%s/temp%d_input", 
              path,i);
         fff=fopen(filename,"r");
         if (fff==NULL) continue;
         fclose(fff);

         snprintf(name, PAPI_MAX_STR_LEN, "%s:temp%i_input", 
             hwmonx->d_name, i);
         snprintf(units, PAPI_MIN_STR_LEN, "degrees C");
         snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
              units,modulename,
              location);

         if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
            goto done_error;
         }

         count++;
      }

      /************************************************************/
      /* Try handling all events starting with fan (fan)          */
      /************************************************************/

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

         /* Try looking for a location label */
         snprintf(filename, PAPI_MAX_STR_LEN, "%s/fan%d_label", 
              path,i);
         fff=fopen(filename,"r");
         if (fff==NULL) {
            strncpy(location,"?",PAPI_MIN_STR_LEN);
         }
         else {
            if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
               location[strlen(location)-1]='\0';
            }
            fclose(fff);
         }

         /* Look for input fan */
         snprintf(filename, PAPI_MAX_STR_LEN, "%s/fan%d_input", 
              path,i);
         fff=fopen(filename,"r");
         if (fff==NULL) continue;
         fclose(fff);

         snprintf(name, PAPI_MAX_STR_LEN, "%s:fan%i_input", 
             hwmonx->d_name, i);
         snprintf(units, PAPI_MIN_STR_LEN, "RPM");
         snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
              units,modulename,
              location);

         if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
            goto done_error;
         }

         count++;

      }
      closedir(d);
     }
       }
    }

    closedir(dir);
    return count;

done_error:
    closedir(d);
    closedir(dir);
    return PAPI_ECMP;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static long long getEventValue ( int  index) [static]

Definition at line 295 of file linux-coretemp.c.

{
    char buf[PAPI_MAX_STR_LEN];
    FILE* fp;
    long result;

    if (_coretemp_native_events[index].stone) {
       return _coretemp_native_events[index].value;
    }

    fp = fopen(_coretemp_native_events[index].path, "r");
    if (fp==NULL) {
       return INVALID_RESULT;
    }

    if (fgets(buf, PAPI_MAX_STR_LEN, fp)==NULL) {
        result=INVALID_RESULT;
    }
    else {
        result=strtoll(buf, NULL, 10);
    }
    fclose(fp);

    return result;
}

Here is the caller graph for this function:

static int insert_in_list ( char *  name,
char *  units,
char *  description,
char *  filename 
) [static]

Definition at line 44 of file linux-coretemp.c.

                                              {


    struct temp_event *temp;


    /* new_event   path, events->d_name */
    temp = (struct temp_event *) papi_calloc(sizeof(struct temp_event),1);
    if (temp==NULL) {
       PAPIERROR("out of memory!");
       /* We should also free any previously allocated data */
       return PAPI_ENOMEM;
    }

    temp->next = NULL;

    if (root == NULL) {
       root = temp;
    }
    else if (last) {
       last->next = temp;
    }
    else {
           /* Because this is a function, it is possible */
           /* we are called with root!=NULL but no last  */
           /* so add this to keep coverity happy         */
           free(temp);
           PAPIERROR("This shouldn't be possible\n");

           return PAPI_ECMP;
    }

    last = temp;

    snprintf(temp->name, PAPI_MAX_STR_LEN, "%s", name);
    snprintf(temp->units, PAPI_MIN_STR_LEN, "%s", units);
    snprintf(temp->description, PAPI_MAX_STR_LEN, "%s", description);
    snprintf(temp->path, PATH_MAX, "%s", filename);

    return PAPI_OK;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 17 of file linux-coretemp.c.

int is_initialized = 0 [static]

Definition at line 34 of file linux-coretemp.c.

struct temp_event* last = NULL [static]

Definition at line 41 of file linux-coretemp.c.

int num_events = 0 [static]

Definition at line 33 of file linux-coretemp.c.

struct temp_event* root = NULL [static]

Definition at line 40 of file linux-coretemp.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines