PAPI  5.4.0.0
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
linux-lmsensors.c
Go to the documentation of this file.
1 
31 /* Headers required by libsensors */
32 #include <sensors.h>
33 #include <error.h>
34 #include <time.h>
35 #include <string.h>
36 
37 /* Headers required by PAPI */
38 #include "papi.h"
39 #include "papi_internal.h"
40 #include "papi_vector.h"
41 #include "papi_memory.h"
42 
43 /************************* DEFINES SECTION ***********************************
44  *******************************************************************************/
45 /* this number assumes that there will never be more events than indicated */
46 #define LM_SENSORS_MAX_COUNTERS 512
47 // time in usecs
48 #define LM_SENSORS_REFRESHTIME 200000
49 
51 typedef struct _lmsensors_register
52 {
53  /* This is used by the framework.It likes it to be !=0 to do somehting */
54  unsigned int selector;
55  /* These are the only information needed to locate a libsensors event */
56  const sensors_chip_name *name;
59 
60 /*
61  * The following structures mimic the ones used by other components. It is more
62  * convenient to use them like that as programming with PAPI makes specific
63  * assumptions for them.
64  */
65 
67 typedef struct _lmsensors_native_event_entry
68 {
71  char description[PAPI_MAX_STR_LEN];
72  unsigned int count;
74 
75 
76 typedef struct _lmsensors_reg_alloc
77 {
80 
81 
82 typedef struct _lmsensors_control_state
83 {
84  long_long counts[LM_SENSORS_MAX_COUNTERS]; // used for caching
87 
88 
89 typedef struct _lmsensors_context
90 {
93 
94 
95 
96 /************************* GLOBALS SECTION ***********************************
97  *******************************************************************************/
98 /* This table contains the LM_SENSORS native events */
100 /* number of events in the table*/
101 static int num_events = 0;
102 
103 
104 
106 
107 /******************************************************************************
108  ******** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT ********
109  *****************************************************************************/
110 /*
111  * Counts number of events available in this system
112  */
113 static unsigned
115 {
116  unsigned id = 0;
117  int chip_nr = 0;
118  const sensors_chip_name *chip_name;
119 
120  /* Loop through all the chips, features, subfeatures found */
121  while ( ( chip_name =
122  sensors_get_detected_chips( NULL, &chip_nr ) ) != NULL ) {
123  int a = 0, b;
124  const sensors_feature *feature;
125 
126  while ( ( feature = sensors_get_features( chip_name, &a ) ) ) {
127  b = 0;
128  while ( ( sensors_get_all_subfeatures( chip_name, feature,
129  &b ) ) ) {
130  id++;
131  }
132  }
133  }
134 
135  return id;
136 }
137 
138 
139 /*
140  * Create the native events for particulare component (!= 0)
141  */
142 static unsigned
144 {
145  unsigned id = 0;
146  unsigned int count = 0;
147 
148  int chip_nr = 0;
149  const sensors_chip_name *chip_name;
150 
151  /* component name and description */
152  strcpy( _lmsensors_vector.cmp_info.short_name, "LM_SENSORS" );
153  strcpy( _lmsensors_vector.cmp_info.description,
154  "lm-sensors provides tools for monitoring the hardware health" );
155 
156 
157  /* Loop through all the chips found */
158  while ( ( chip_name =
159  sensors_get_detected_chips( NULL, &chip_nr ) ) != NULL ) {
160  int a, b;
161  const sensors_feature *feature;
162  const sensors_subfeature *sub;
163  char chipnamestring[PAPI_MIN_STR_LEN];
164 
165  // lm_sensors_native_table[id].count = 0;
166 
167  /* get chip name from its internal representation */
168  sensors_snprintf_chip_name( chipnamestring,
169  PAPI_MIN_STR_LEN, chip_name );
170 
171  a = 0;
172 
173  /* Loop through all the features found */
174  while ( ( feature = sensors_get_features( chip_name, &a ) ) ) {
175  char *featurelabel;
176 
177  if ( !( featurelabel = sensors_get_label( chip_name, feature ))) {
178  fprintf( stderr, "ERROR: Can't get label of feature %s!\n",
179  feature->name );
180  continue;
181  }
182 
183  b = 0;
184 
185  /* Loop through all the subfeatures found */
186  while ((sub=sensors_get_all_subfeatures(chip_name,feature,&b))) {
187 
188  count = 0;
189 
190  /* Save native event data */
191  sprintf( lm_sensors_native_table[id].name, "%s.%s.%s.%s",
192  _lmsensors_vector.cmp_info.short_name,
193  chipnamestring, featurelabel, sub->name );
194 
195  strncpy( lm_sensors_native_table[id].description,
196  lm_sensors_native_table[id].name, PAPI_MAX_STR_LEN );
197 
198  /* The selector has to be !=0 . Starts with 1 */
199  lm_sensors_native_table[id].resources.selector = id + 1;
200 
201  /* Save the actual references to this event */
202  lm_sensors_native_table[id].resources.name = chip_name;
203  lm_sensors_native_table[id].resources.subfeat_nr = sub->number;
204 
205  count = sub->number;
206 
207  /* increment the table index counter */
208  id++;
209  }
210 
211  // lm_sensors_native_table[id].count = count + 1;
212  free( featurelabel );
213  }
214  }
215 
216  /* Return the number of events created */
217  return id;
218 }
219 
220 /*
221  * Returns the value of the event with index 'i' in lm_sensors_native_table
222  * This value is scaled by 1000 to cope with the lack to return decimal numbers
223  * with PAPI
224  */
225 
226 static long_long
227 getEventValue( unsigned event_id )
228 {
229  double value;
230  int res;
231 
232  res = sensors_get_value( lm_sensors_native_table[event_id].resources.name,
233  lm_sensors_native_table[event_id].resources.
234  subfeat_nr, &value );
235 
236  if ( res < 0 ) {
237  fprintf( stderr, "libsensors(): Could not read event #%d!\n",
238  event_id );
239  return -1;
240  }
241 
242  return ( ( long_long ) ( value * 1000 ) );
243 }
244 
245 
246 /*****************************************************************************
247  ******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS *************
248  *****************************************************************************/
249 
250 /*
251  * This is called whenever a thread is initialized
252  */
253 int
255 {
256  ( void ) ctx;
257  return PAPI_OK;
258 }
259 
260 
261 /* Initialize hardware counters, setup the function vector table
262  * and get hardware information, this routine is called when the
263  * PAPI process is initialized (IE PAPI_library_init)
264  */
265 int
267 {
268  int res;
269  (void) cidx;
270 
271  /* Initialize libsensors library */
272  if ( ( res = sensors_init( NULL ) ) != 0 ) {
273  strncpy(_lmsensors_vector.cmp_info.disabled_reason,
274  "Cannot enable libsensors",PAPI_MAX_STR_LEN);
275  return res;
276  }
277 
278  /* Create dyanmic events table */
280  SUBDBG("Found %d sensors\n",num_events);
281 
282  if ( ( lm_sensors_native_table =
283  calloc( num_events, sizeof ( _lmsensors_native_event_entry_t )))
284  == NULL ) {
285  strncpy(_lmsensors_vector.cmp_info.disabled_reason,
286  "Could not malloc room",PAPI_MAX_STR_LEN);
287  return PAPI_ENOMEM;
288  }
289 
290  if ( ( unsigned ) num_events != createNativeEvents( ) ) {
291  strncpy(_lmsensors_vector.cmp_info.disabled_reason,
292  "LM_SENSOR number mismatch",PAPI_MAX_STR_LEN);
293  return PAPI_ECMP;
294  }
295 
296  _lmsensors_vector.cmp_info.num_native_events=num_events;
297  _lmsensors_vector.cmp_info.num_cntrs=num_events;
298 
299  return PAPI_OK;
300 }
301 
302 
303 /*
304  * Control of counters (Reading/Writing/Starting/Stopping/Setup)
305  * functions
306  */
307 int
309 {
310  int i;
311 
312  for ( i = 0; i < num_events; i++ )
313  ( ( _lmsensors_control_state_t * ) ctl )->counts[i] =
314  getEventValue( i );
315 
316  ( ( _lmsensors_control_state_t * ) ctl )->lastupdate =
318  return PAPI_OK;
319 }
320 
321 
322 /*
323  *
324  */
325 int
327 {
328  ( void ) ctx;
329  ( void ) ctl;
330 
331  return PAPI_OK;
332 }
333 
334 
335 /*
336  *
337  */
338 int
340 {
341  ( void ) ctx;
342  ( void ) ctl;
343 
344  return PAPI_OK;
345 }
346 
347 
348 /*
349  *
350  */
351 int
353  long_long ** events, int flags )
354 {
355  ( void ) ctx;
356  ( void ) flags;
357  long long start = PAPI_get_real_usec( );
358  int i;
359 
361 
362  if ( start - control->lastupdate > 200000 ) { // cache refresh
363 
364  for ( i = 0; i < num_events; i++ ) {
365  control->counts[i] = getEventValue( i );
366  }
367  control->lastupdate = PAPI_get_real_usec( );
368  }
369 
370  *events = control->counts;
371  return PAPI_OK;
372 }
373 
374 
375 int
377 {
378 
379  /* Call the libsensors cleaning function before leaving */
380  sensors_cleanup( );
381 
382  return PAPI_OK;
383 }
384 
385 int
387 {
388  ( void ) ctx;
389 
390  return PAPI_OK;
391 }
392 
393 
394 
395 /* This function sets various options in the component
396  * The valid codes being passed in are PAPI_SET_DEFDOM,
397  * PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
398  */
399 int
401 {
402  ( void ) ctx;
403  ( void ) code;
404  ( void ) option;
405  return PAPI_OK;
406 }
407 
408 
409 int
411  NativeInfo_t * native,
412  int count,
413  hwd_context_t *ctx )
414 {
415  int i, index;
416  ( void ) ctx;
417  ( void ) ctl;
418 
419  for ( i = 0; i < count; i++ ) {
420  index = native[i].ni_event;
421  native[i].ni_position =
422  lm_sensors_native_table[index].resources.selector - 1;
423  }
424  return PAPI_OK;
425 }
426 
427 
428 /*
429  * As I understand it, all data reported by these interfaces will be system wide
430  */
431 int
433 {
434  (void) ctl;
435  if ( PAPI_DOM_ALL != domain )
436  return ( PAPI_EINVAL );
437 
438  return ( PAPI_OK );
439 }
440 
441 
442 /*
443  *
444  */
445 int
447 {
448  ( void ) ctx;
449  ( void ) ctl;
450  return PAPI_OK;
451 }
452 
453 
454 /*
455  * Native Event functions
456  */
457 int
458 _lmsensors_ntv_enum_events( unsigned int *EventCode, int modifier )
459 {
460 
461  switch ( modifier ) {
462  case PAPI_ENUM_FIRST:
463  *EventCode = 0;
464 
465  return PAPI_OK;
466  break;
467 
468  case PAPI_ENUM_EVENTS:
469  {
470  int index = *EventCode;
471 
472  if ( index < num_events - 1 ) {
473  *EventCode = *EventCode + 1;
474  return PAPI_OK;
475  } else
476  return PAPI_ENOEVNT;
477 
478  break;
479  }
480  default:
481  return PAPI_EINVAL;
482  }
483  return PAPI_EINVAL;
484 }
485 
486 /*
487  *
488  */
489 int
490 _lmsensors_ntv_code_to_name( unsigned int EventCode, char *name, int len )
491 {
492  int index = EventCode;
493 
494  if (index>=0 && index<num_events) {
495  strncpy( name, lm_sensors_native_table[index].name, len );
496  }
497 
498  return PAPI_OK;
499 }
500 
501 /*
502  *
503  */
504 int
505 _lmsensors_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
506 {
507  int index = EventCode;
508 
509  if (index>=0 && index<num_events) {
510  strncpy( name, lm_sensors_native_table[index].description, len );
511  }
512  return PAPI_OK;
513 }
514 
515 
516 
517 /*
518  *
519  */
520 papi_vector_t _lmsensors_vector = {
521  .cmp_info = {
522  /* component information (unspecified values are initialized to 0) */
523  .name = "lmsensors",
524  .short_name = "lmsensors",
525  .version = "5.0",
526  .description = "Linux LMsensor statistics",
527  .num_mpx_cntrs = LM_SENSORS_MAX_COUNTERS,
528  .num_cntrs = LM_SENSORS_MAX_COUNTERS,
529  .default_domain = PAPI_DOM_ALL,
530  .available_domains = PAPI_DOM_ALL,
531  .default_granularity = PAPI_GRN_SYS,
532  .available_granularities = PAPI_GRN_SYS,
533  .hardware_intr_sig = PAPI_INT_SIGNAL,
534 
535  /* component specific cmp_info initializations */
536  .fast_real_timer = 0,
537  .fast_virtual_timer = 0,
538  .attach = 0,
539  .attach_must_ptrace = 0,
540  .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
541  },
542 
543  /* sizes of framework-opaque component-private structures */
544  .size = {
545  .context = sizeof ( _lmsensors_context_t ),
546  .control_state = sizeof ( _lmsensors_control_state_t ),
547  .reg_value = sizeof ( _lmsensors_register_t ),
548  .reg_alloc = sizeof ( _lmsensors_reg_alloc_t ),
549  },
550  /* function pointers in this component */
551  .init_thread = _lmsensors_init_thread,
552  .init_component = _lmsensors_init_component,
553  .init_control_state = _lmsensors_init_control_state,
554  .start = _lmsensors_start,
555  .stop = _lmsensors_stop,
556  .read = _lmsensors_read,
557  .shutdown_thread = _lmsensors_shutdown_thread,
558  .shutdown_component = _lmsensors_shutdown_component,
559  .ctl = _lmsensors_ctl,
560  .update_control_state = _lmsensors_update_control_state,
561  .set_domain = _lmsensors_set_domain,
562  .reset = _lmsensors_reset,
563 
564  .ntv_enum_events = _lmsensors_ntv_enum_events,
565  .ntv_code_to_name = _lmsensors_ntv_code_to_name,
566  .ntv_code_to_descr = _lmsensors_ntv_code_to_descr,
567 };
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:626
#define PAPI_ENOEVNT
Definition: papi.h:258
int _lmsensors_init_thread(hwd_context_t *ctx)
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
int _lmsensors_init_component(int cidx)
long long flags
Definition: iozone.c:12330
int _lmsensors_init_control_state(hwd_control_state_t *ctl)
start
Definition: iozone.c:22736
unsigned int count
static int num_events
#define PAPI_DOM_KERNEL
Definition: papi.h:298
long_long counts[LM_SENSORS_MAX_COUNTERS]
static unsigned createNativeEvents(void)
int _lmsensors_update_control_state(hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
#define PAPI_DOM_ALL
Definition: papi.h:301
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
#define PAPI_DOM_USER
Definition: papi.h:296
void
Definition: iozone.c:18627
return PAPI_EINVAL
Definition: linux-nvml.c:408
PAPI_component_info_t cmp_info
Definition: papi_vector.h:20
char short_name[PAPI_MIN_STR_LEN]
Definition: papi.h:627
void double value
Definition: iozone.c:18781
static double a[MATRIX_SIZE][MATRIX_SIZE]
Definition: rapl_basic.c:37
Return codes and api definitions.
int _lmsensors_read(hwd_context_t *ctx, hwd_control_state_t *ctl, long_long **events, int flags)
char events[MAX_EVENTS][BUFSIZ]
char disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:633
static unsigned detectSensors(void)
static long_long getEventValue(unsigned event_id)
int i
Definition: fileop.c:140
int _lmsensors_start(hwd_context_t *ctx, hwd_control_state_t *ctl)
free(dummyfile[xx])
static int cidx
Definition: event_info.c:40
int _lmsensors_ntv_code_to_descr(unsigned int EventCode, char *name, int len)
static int native
Definition: event_info.c:39
#define SUBDBG(format, args...)
Definition: papi_debug.h:63
#define LM_SENSORS_MAX_COUNTERS
#define PAPI_ECMP
Definition: papi.h:254
static _lmsensors_native_event_entry_t * lm_sensors_native_table
char description[PAPI_MAX_STR_LEN]
Definition: papi.h:629
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
uint32_t id
Definition: linux-cuda.c:293
#define PAPI_ENOMEM
Definition: papi.h:252
char name[PAPI_MAX_STR_LEN]
strcpy(filename, default_filename)
static double b[MATRIX_SIZE][MATRIX_SIZE]
Definition: rapl_basic.c:38
long long PAPI_get_real_usec(void)
Definition: papi.c:6190
int _lmsensors_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
char * name
Definition: iozone.c:23648
#define PAPI_MIN_STR_LEN
Definition: papi.h:462
#define long_long
Definition: papi.h:550
int _lmsensors_ntv_code_to_name(unsigned int EventCode, char *name, int len)
_lmsensors_control_state_t state
int _lmsensors_shutdown_thread(hwd_context_t *ctx)
int _lmsensors_ctl(hwd_context_t *ctx, int code, _papi_int_option_t *option)
#define PAPI_MAX_STR_LEN
Definition: papi.h:463
int _lmsensors_stop(hwd_context_t *ctx, hwd_control_state_t *ctl)
int _lmsensors_set_domain(hwd_control_state_t *ctl, int domain)
papi_vector_t _lmsensors_vector
int _lmsensors_shutdown_component(void)
#define PAPI_GRN_SYS
Definition: papi.h:364
const sensors_chip_name * name
int _lmsensors_ntv_enum_events(unsigned int *EventCode, int modifier)
_lmsensors_register_t resources
_lmsensors_register_t ra_bits