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.

00503 {
00504     ( void ) ctx;
00505     ( void ) code;
00506     ( void ) option;
00507 
00508     return PAPI_OK;
00509 }

int _coretemp_init_component ( int  cidx  ) 

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     strncpy(_coretemp_native_events[i].path,t->path,PATH_MAX);
00377     strncpy(_coretemp_native_events[i].units,t->units,PAPI_MIN_STR_LEN);
00378     strncpy(_coretemp_native_events[i].description,t->description,
00379             PAPI_MAX_STR_LEN);
00380     _coretemp_native_events[i].stone = 0;
00381     _coretemp_native_events[i].resources.selector = i + 1;
00382     last    = t;
00383     t       = t->next;
00384     papi_free(last);
00385     i++;
00386      } while (t != NULL);
00387      root = NULL;
00388 
00389      /* Export the total number of events available */
00390      _coretemp_vector.cmp_info.num_native_events = num_events;
00391 
00392      /* Export the component id */
00393      _coretemp_vector.cmp_info.CmpIdx = cidx;
00394 
00395      return PAPI_OK;
00396 }

Here is the call graph for this function:

int _coretemp_init_control_state ( hwd_control_state_t ctl  ) 

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

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

Here is the call graph for this function:

int _coretemp_init_thread ( hwd_context_t ctx  ) 

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

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

int _coretemp_ntv_code_to_descr ( unsigned int  EventCode,
char *  name,
int  len 
)

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

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

int _coretemp_ntv_code_to_info ( unsigned int  EventCode,
PAPI_event_info_t info 
)

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

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

int _coretemp_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

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

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

int _coretemp_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

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

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

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.

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

Here is the call graph for this function:

int _coretemp_reset ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

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

00552 {
00553     ( void ) ctx;
00554     ( void ) ctl;
00555     
00556     return PAPI_OK;
00557 }

int _coretemp_set_domain ( hwd_control_state_t cntl,
int  domain 
)

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

00541 {
00542        (void) cntl;
00543        if ( PAPI_DOM_ALL != domain )
00544         return PAPI_EINVAL;
00545 
00546        return PAPI_OK;
00547 }

int _coretemp_shutdown_component (  ) 

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

00487 {
00488     if ( is_initialized ) {
00489        is_initialized = 0;
00490        papi_free(_coretemp_native_events);
00491        _coretemp_native_events = NULL;
00492     }
00493     return PAPI_OK;
00494 }

int _coretemp_shutdown_thread ( hwd_context_t ctx  ) 

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

00476 {
00477   ( void ) ctx;
00478   return PAPI_OK;
00479 }

int _coretemp_start ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

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

00424 {
00425   ( void ) ctx;
00426   ( void ) ctl;
00427 
00428   return PAPI_OK;
00429 }

int _coretemp_stop ( hwd_context_t ctx,
hwd_control_state_t ctl 
)

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

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

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.

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

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 26 Jan 2016 for PAPI by  doxygen 1.6.1