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)
static int _coretemp_init_thread (hwd_context_t *ctx)
static int _coretemp_init_component (int cidx)
static int _coretemp_init_control_state (hwd_control_state_t *ctl)
static int _coretemp_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _coretemp_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long long **events, int flags)
static int _coretemp_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _coretemp_shutdown_thread (hwd_context_t *ctx)
static int _coretemp_shutdown_component ()
static int _coretemp_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
static int _coretemp_update_control_state (hwd_control_state_t *ptr, NativeInfo_t *native, int count, hwd_context_t *ctx)
static int _coretemp_set_domain (hwd_control_state_t *cntl, int domain)
static int _coretemp_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
static int _coretemp_ntv_enum_events (unsigned int *EventCode, int modifier)
static int _coretemp_ntv_code_to_name (unsigned int EventCode, char *name, int len)
static int _coretemp_ntv_code_to_descr (unsigned int EventCode, char *name, int len)
static 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

static int _coretemp_ctl ( hwd_context_t ctx,
int  code,
_papi_int_option_t option 
) [static]

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

00506 {
00507     ( void ) ctx;
00508     ( void ) code;
00509     ( void ) option;
00510 
00511     return PAPI_OK;
00512 }

static int _coretemp_init_component ( int  cidx  )  [static]

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

00343 {
00344      int i = 0;
00345      struct temp_event *t,*last;
00346 
00347      if ( is_initialized )
00348     return (PAPI_OK );
00349 
00350      is_initialized = 1;
00351 
00352      /* This is the prefered method, all coretemp sensors are symlinked here
00353       * see $(kernel_src)/Documentation/hwmon/sysfs-interface */
00354   
00355      num_events = generateEventList("/sys/class/hwmon");
00356 
00357      if ( num_events < 0 ) {
00358         strncpy(_coretemp_vector.cmp_info.disabled_reason,
00359         "Cannot open /sys/class/hwmon",PAPI_MAX_STR_LEN);
00360     return PAPI_ENOCMP;
00361      }
00362 
00363      if ( num_events == 0 ) {
00364         strncpy(_coretemp_vector.cmp_info.disabled_reason,
00365         "No coretemp events found",PAPI_MAX_STR_LEN);
00366     return PAPI_ENOCMP;
00367      }
00368 
00369      t = root;
00370   
00371      _coretemp_native_events = (CORETEMP_native_event_entry_t*)
00372           papi_calloc(sizeof(CORETEMP_native_event_entry_t),num_events);
00373 
00374      do {
00375     strncpy(_coretemp_native_events[i].name,t->name,PAPI_MAX_STR_LEN);
00376         _coretemp_native_events[i].name[PAPI_MAX_STR_LEN-1] = '\0';
00377     strncpy(_coretemp_native_events[i].path,t->path,PATH_MAX);
00378         _coretemp_native_events[i].path[PATH_MAX-1] = '\0';
00379     strncpy(_coretemp_native_events[i].units,t->units,PAPI_MIN_STR_LEN);
00380     _coretemp_native_events[i].units[PAPI_MIN_STR_LEN-1] = '\0';
00381     strncpy(_coretemp_native_events[i].description,t->description,PAPI_MAX_STR_LEN);
00382         _coretemp_native_events[i].description[PAPI_MAX_STR_LEN-1] = '\0';
00383     _coretemp_native_events[i].stone = 0;
00384     _coretemp_native_events[i].resources.selector = i + 1;
00385     last    = t;
00386     t       = t->next;
00387     papi_free(last);
00388     i++;
00389      } while (t != NULL);
00390      root = NULL;
00391 
00392      /* Export the total number of events available */
00393      _coretemp_vector.cmp_info.num_native_events = num_events;
00394 
00395      /* Export the component id */
00396      _coretemp_vector.cmp_info.CmpIdx = cidx;
00397 
00398      return PAPI_OK;
00399 }

Here is the call graph for this function:

static int _coretemp_init_control_state ( hwd_control_state_t ctl  )  [static]

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

00410 {
00411     int i;
00412 
00413     CORETEMP_control_state_t *coretemp_ctl = (CORETEMP_control_state_t *) ctl;
00414 
00415     for ( i=0; i < num_events; i++ ) {
00416     coretemp_ctl->counts[i] = getEventValue(i);
00417     }
00418 
00419     /* Set last access time for caching results */
00420     coretemp_ctl->lastupdate = PAPI_get_real_usec();
00421 
00422     return PAPI_OK;
00423 }

Here is the call graph for this function:

static int _coretemp_init_thread ( hwd_context_t ctx  )  [static]

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

00330 {
00331   ( void ) ctx;
00332   return PAPI_OK;
00333 }

static int _coretemp_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
) [static]

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

00622 {
00623      int index = EventCode;
00624 
00625      if ( index >= 0 && index < num_events ) {
00626     strncpy( name, _coretemp_native_events[index].description, len );
00627     return PAPI_OK;
00628      }
00629      return PAPI_ENOEVNT;
00630 }

static int _coretemp_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
) [static]

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

00634 {
00635 
00636   int index = EventCode;
00637 
00638   if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
00639 
00640   strncpy( info->symbol, _coretemp_native_events[index].name, sizeof(info->symbol));
00641   strncpy( info->long_descr, _coretemp_native_events[index].description, sizeof(info->long_descr));
00642   strncpy( info->units, _coretemp_native_events[index].units, sizeof(info->units));
00643   info->units[sizeof(info->units)-1] = '\0';
00644 
00645   return PAPI_OK;
00646 }

static int _coretemp_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
) [static]

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

00607 {
00608      int index = EventCode;
00609 
00610      if ( index >= 0 && index < num_events ) {
00611     strncpy( name, _coretemp_native_events[index].name, len );
00612     return PAPI_OK;
00613      }
00614      return PAPI_ENOEVNT;
00615 }

static int _coretemp_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
) [static]

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

00568 {
00569 
00570      int index;
00571 
00572      switch ( modifier ) {
00573 
00574     case PAPI_ENUM_FIRST:
00575 
00576        if (num_events==0) {
00577           return PAPI_ENOEVNT;
00578        }
00579        *EventCode = 0;
00580 
00581        return PAPI_OK;
00582         
00583 
00584     case PAPI_ENUM_EVENTS:
00585     
00586        index = *EventCode;
00587 
00588        if ( index < num_events - 1 ) {
00589           *EventCode = *EventCode + 1;
00590           return PAPI_OK;
00591        } else {
00592           return PAPI_ENOEVNT;
00593        }
00594        break;
00595     
00596     default:
00597         return PAPI_EINVAL;
00598     }
00599     return PAPI_EINVAL;
00600 }

static int _coretemp_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long long **  events,
int  flags 
) [static]

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

00437 {
00438     (void) flags;
00439     (void) ctx;
00440 
00441     CORETEMP_control_state_t* control = (CORETEMP_control_state_t*) ctl;
00442     long long now = PAPI_get_real_usec();
00443     int i;
00444 
00445     /* Only read the values from the kernel if enough time has passed */
00446     /* since the last read.  Otherwise return cached values.          */
00447 
00448     if ( now - control->lastupdate > REFRESH_LAT ) {
00449     for ( i = 0; i < num_events; i++ ) {
00450        control->counts[i] = getEventValue( i );
00451     }
00452     control->lastupdate = now;
00453     }
00454 
00455     /* Pass back a pointer to our results */
00456     *events = control->counts;
00457 
00458     return PAPI_OK;
00459 }

Here is the call graph for this function:

static int _coretemp_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

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

00555 {
00556     ( void ) ctx;
00557     ( void ) ctl;
00558     
00559     return PAPI_OK;
00560 }

static int _coretemp_set_domain ( hwd_control_state_t cntl,
int  domain 
) [static]

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

00544 {
00545        (void) cntl;
00546        if ( PAPI_DOM_ALL != domain )
00547         return PAPI_EINVAL;
00548 
00549        return PAPI_OK;
00550 }

static int _coretemp_shutdown_component (  )  [static]

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

00490 {
00491     if ( is_initialized ) {
00492        is_initialized = 0;
00493        papi_free(_coretemp_native_events);
00494        _coretemp_native_events = NULL;
00495     }
00496     return PAPI_OK;
00497 }

static int _coretemp_shutdown_thread ( hwd_context_t ctx  )  [static]

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

00479 {
00480   ( void ) ctx;
00481   return PAPI_OK;
00482 }

static int _coretemp_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

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

00427 {
00428   ( void ) ctx;
00429   ( void ) ctl;
00430 
00431   return PAPI_OK;
00432 }

static int _coretemp_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
) [static]

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

00463 {
00464     (void) ctx;
00465     /* read values */
00466     CORETEMP_control_state_t* control = (CORETEMP_control_state_t*) ctl;
00467     int i;
00468 
00469     for ( i = 0; i < num_events; i++ ) {
00470     control->counts[i] = getEventValue( i );
00471     }
00472 
00473     return PAPI_OK;
00474 }

Here is the call graph for this function:

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

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

00519 {
00520     int i, index;
00521     ( void ) ctx;
00522     ( void ) ptr;
00523 
00524     for ( i = 0; i < count; i++ ) {
00525     index = native[i].ni_event;
00526     native[i].ni_position = _coretemp_native_events[index].resources.selector - 1;
00527     }
00528     return PAPI_OK;
00529 }

static int generateEventList ( char *  base_dir  )  [static]

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

00092 {
00093     char path[PATH_MAX],filename[PATH_MAX];
00094     char modulename[PAPI_MIN_STR_LEN],
00095          location[PAPI_MIN_STR_LEN],
00096          units[PAPI_MIN_STR_LEN],
00097          description[PAPI_MAX_STR_LEN],
00098          name[PAPI_MAX_STR_LEN];
00099     DIR *dir,*d;
00100     FILE *fff;
00101     int count = 0;
00102     struct dirent *hwmonx;
00103     int i,pathnum;
00104 
00105 #define NUM_PATHS 2
00106     char paths[NUM_PATHS][PATH_MAX]={
00107       "device","."
00108     };
00109 
00110     /* Open "/sys/class/hwmon" */
00111     dir = opendir(base_dir);
00112     if ( dir == NULL ) {
00113        SUBDBG("Can't find %s, are you sure the coretemp module is loaded?\n", 
00114            base_dir);
00115        return 0;
00116     }
00117 
00118     /* Iterate each /sys/class/hwmonX/device directory */
00119     while( (hwmonx = readdir(dir) ) ) {
00120        if ( !strncmp("hwmon", hwmonx->d_name, 5) ) {
00121 
00122      /* Found a hwmon directory */
00123 
00124      /* Sometimes the files are in ./, sometimes in device/ */
00125      for(pathnum=0;pathnum<NUM_PATHS;pathnum++) {
00126 
00127         snprintf(path, PATH_MAX, "%s/%s/%s", 
00128              base_dir, hwmonx->d_name,paths[pathnum]);
00129 
00130         SUBDBG("Trying to open %s\n",path);
00131         d = opendir(path);
00132         if (d==NULL) {
00133            continue;
00134         }
00135 
00136         /* Get the name of the module */
00137 
00138         snprintf(filename, PAPI_MAX_STR_LEN, "%s/name",path);
00139         fff=fopen(filename,"r");
00140         if (fff==NULL) {
00141            snprintf(modulename, PAPI_MIN_STR_LEN, "Unknown");
00142         } else {
00143            if (fgets(modulename,PAPI_MIN_STR_LEN,fff)!=NULL) {
00144               modulename[strlen(modulename)-1]='\0';
00145            }
00146            fclose(fff);
00147         }
00148 
00149         SUBDBG("Found module %s\n",modulename);
00150 
00151       /******************************************************/
00152       /* Try handling all events starting with in (voltage) */
00153       /******************************************************/
00154 
00155 
00156         /* arbitrary maximum */
00157         /* the problem is the numbering can be sparse */
00158         /* should probably go back to dirent listing  */
00159         
00160       for(i=0;i<32;i++) {
00161 
00162          /* Try looking for a location label */
00163          snprintf(filename, PAPI_MAX_STR_LEN, "%s/in%d_label", 
00164               path,i);
00165          fff=fopen(filename,"r");
00166          if (fff==NULL) {
00167             strncpy(location,"?",PAPI_MIN_STR_LEN);
00168          }
00169          else {
00170             if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
00171                location[strlen(location)-1]='\0';
00172             }
00173             fclose(fff);
00174          }
00175 
00176          /* Look for input temperature */
00177          snprintf(filename, PAPI_MAX_STR_LEN, "%s/in%d_input", 
00178               path,i);
00179          fff=fopen(filename,"r");
00180          if (fff==NULL) continue;
00181          fclose(fff);
00182 
00183          snprintf(name, PAPI_MAX_STR_LEN, "%s:in%i_input", 
00184              hwmonx->d_name, i);
00185          snprintf(units, PAPI_MIN_STR_LEN, "V");
00186          snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
00187               units,modulename,
00188               location);
00189 
00190          if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
00191             goto done_error;
00192          }
00193 
00194          count++;
00195 
00196       }
00197 
00198       /************************************************************/
00199       /* Try handling all events starting with temp (temperature) */
00200       /************************************************************/
00201 
00202       for(i=0;i<32;i++) {
00203 
00204          /* Try looking for a location label */
00205          snprintf(filename, PAPI_MAX_STR_LEN, "%s/temp%d_label", 
00206               path,i);
00207          fff=fopen(filename,"r");
00208          if (fff==NULL) {
00209             strncpy(location,"?",PAPI_MIN_STR_LEN);
00210          }
00211          else {
00212             if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
00213                location[strlen(location)-1]='\0';
00214             }
00215             fclose(fff);
00216          }
00217 
00218          /* Look for input temperature */
00219          snprintf(filename, PAPI_MAX_STR_LEN, "%s/temp%d_input", 
00220               path,i);
00221          fff=fopen(filename,"r");
00222          if (fff==NULL) continue;
00223          fclose(fff);
00224 
00225          snprintf(name, PAPI_MAX_STR_LEN, "%s:temp%i_input", 
00226              hwmonx->d_name, i);
00227          snprintf(units, PAPI_MIN_STR_LEN, "degrees C");
00228          snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
00229               units,modulename,
00230               location);
00231 
00232          if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
00233             goto done_error;
00234          }
00235 
00236          count++;
00237       }
00238 
00239       /************************************************************/
00240       /* Try handling all events starting with fan (fan)          */
00241       /************************************************************/
00242 
00243       for(i=0;i<32;i++) {
00244 
00245          /* Try looking for a location label */
00246          snprintf(filename, PAPI_MAX_STR_LEN, "%s/fan%d_label", 
00247               path,i);
00248          fff=fopen(filename,"r");
00249          if (fff==NULL) {
00250             strncpy(location,"?",PAPI_MIN_STR_LEN);
00251          }
00252          else {
00253             if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
00254                location[strlen(location)-1]='\0';
00255             }
00256             fclose(fff);
00257          }
00258 
00259          /* Look for input fan */
00260          snprintf(filename, PAPI_MAX_STR_LEN, "%s/fan%d_input", 
00261               path,i);
00262          fff=fopen(filename,"r");
00263          if (fff==NULL) continue;
00264          fclose(fff);
00265 
00266          snprintf(name, PAPI_MAX_STR_LEN, "%s:fan%i_input", 
00267              hwmonx->d_name, i);
00268          snprintf(units, PAPI_MIN_STR_LEN, "RPM");
00269          snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
00270               units,modulename,
00271               location);
00272 
00273          if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
00274             goto done_error;
00275          }
00276 
00277          count++;
00278 
00279       }
00280       closedir(d);
00281      }
00282        }
00283     }
00284 
00285     closedir(dir);
00286     return count;
00287 
00288 done_error:
00289     closedir(d);
00290     closedir(dir);
00291     return PAPI_ECMP;
00292 }

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.

00296 {
00297     char buf[PAPI_MAX_STR_LEN];
00298     FILE* fp;
00299     long result;
00300 
00301     if (_coretemp_native_events[index].stone) {
00302        return _coretemp_native_events[index].value;
00303     }
00304 
00305     fp = fopen(_coretemp_native_events[index].path, "r");
00306     if (fp==NULL) {
00307        return INVALID_RESULT;
00308     }
00309 
00310     if (fgets(buf, PAPI_MAX_STR_LEN, fp)==NULL) {
00311         result=INVALID_RESULT;
00312     }
00313     else {
00314         result=strtoll(buf, NULL, 10);
00315     }
00316     fclose(fp);
00317 
00318     return result;
00319 }

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.

00045                                               {
00046 
00047 
00048     struct temp_event *temp;
00049 
00050 
00051     /* new_event   path, events->d_name */
00052     temp = (struct temp_event *) papi_calloc(sizeof(struct temp_event),1);
00053     if (temp==NULL) {
00054        PAPIERROR("out of memory!");
00055        /* We should also free any previously allocated data */
00056        return PAPI_ENOMEM;
00057     }
00058 
00059     temp->next = NULL;
00060 
00061     if (root == NULL) {
00062        root = temp;
00063     }
00064     else if (last) {
00065        last->next = temp;
00066     }
00067     else {
00068            /* Because this is a function, it is possible */
00069            /* we are called with root!=NULL but no last  */
00070            /* so add this to keep coverity happy         */
00071            free(temp);
00072            PAPIERROR("This shouldn't be possible\n");
00073 
00074            return PAPI_ECMP;
00075     }
00076 
00077     last = temp;
00078 
00079     snprintf(temp->name, PAPI_MAX_STR_LEN, "%s", name);
00080     snprintf(temp->units, PAPI_MIN_STR_LEN, "%s", units);
00081     snprintf(temp->description, PAPI_MAX_STR_LEN, "%s", description);
00082     snprintf(temp->path, PATH_MAX, "%s", filename);
00083 
00084     return PAPI_OK;
00085 }

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

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

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.


Generated on 17 Nov 2016 for PAPI by  doxygen 1.6.1