PAPI  5.3.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  * This function has to set the bits needed to count different domains
430  * In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
431  * By default return PAPI_EINVAL if none of those are specified
432  * and PAPI_OK with success
433  * PAPI_DOM_USER is only user context is counted
434  * PAPI_DOM_KERNEL is only the Kernel/OS context is counted
435  * PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
436  * PAPI_DOM_ALL is all of the domains
437  */
438 int
440 {
441  int found = 0;
442  ( void ) ctl;
443 
444  if ( PAPI_DOM_USER & domain )
445  found = 1;
446 
447  if ( PAPI_DOM_KERNEL & domain )
448  found = 1;
449 
450  if ( PAPI_DOM_OTHER & domain )
451  found = 1;
452 
453  if ( !found )
454  return ( PAPI_EINVAL );
455 
456  return ( PAPI_OK );
457 }
458 
459 
460 /*
461  *
462  */
463 int
465 {
466  ( void ) ctx;
467  ( void ) ctl;
468  return PAPI_OK;
469 }
470 
471 
472 /*
473  * Native Event functions
474  */
475 int
476 _lmsensors_ntv_enum_events( unsigned int *EventCode, int modifier )
477 {
478 
479  switch ( modifier ) {
480  case PAPI_ENUM_FIRST:
481  *EventCode = 0;
482 
483  return PAPI_OK;
484  break;
485 
486  case PAPI_ENUM_EVENTS:
487  {
488  int index = *EventCode;
489 
490  if ( index < num_events - 1 ) {
491  *EventCode = *EventCode + 1;
492  return PAPI_OK;
493  } else
494  return PAPI_ENOEVNT;
495 
496  break;
497  }
498  default:
499  return PAPI_EINVAL;
500  }
501  return PAPI_EINVAL;
502 }
503 
504 /*
505  *
506  */
507 int
508 _lmsensors_ntv_code_to_name( unsigned int EventCode, char *name, int len )
509 {
510  int index = EventCode;
511 
512  if (index>=0 && index<num_events) {
513  strncpy( name, lm_sensors_native_table[index].name, len );
514  }
515 
516  return PAPI_OK;
517 }
518 
519 /*
520  *
521  */
522 int
523 _lmsensors_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
524 {
525  int index = EventCode;
526 
527  if (index>=0 && index<num_events) {
528  strncpy( name, lm_sensors_native_table[index].description, len );
529  }
530  return PAPI_OK;
531 }
532 
533 
534 
535 /*
536  *
537  */
538 papi_vector_t _lmsensors_vector = {
539  .cmp_info = {
540  /* component information (unspecified values are initialized to 0) */
541  .name = "lmsensors",
542  .short_name = "lmsensors",
543  .version = "5.0",
544  .description = "Linux LMsensor statistics",
545  .num_mpx_cntrs = LM_SENSORS_MAX_COUNTERS,
546  .num_cntrs = LM_SENSORS_MAX_COUNTERS,
547  .default_domain = PAPI_DOM_USER,
548  //.available_domains = PAPI_DOM_USER,
549  .default_granularity = PAPI_GRN_THR,
550  .available_granularities = PAPI_GRN_THR,
551  .hardware_intr_sig = PAPI_INT_SIGNAL,
552 
553  /* component specific cmp_info initializations */
554  .fast_real_timer = 0,
555  .fast_virtual_timer = 0,
556  .attach = 0,
557  .attach_must_ptrace = 0,
558  .available_domains = PAPI_DOM_USER | PAPI_DOM_KERNEL,
559  },
560 
561  /* sizes of framework-opaque component-private structures */
562  .size = {
563  .context = sizeof ( _lmsensors_context_t ),
564  .control_state = sizeof ( _lmsensors_control_state_t ),
565  .reg_value = sizeof ( _lmsensors_register_t ),
566  .reg_alloc = sizeof ( _lmsensors_reg_alloc_t ),
567  },
568  /* function pointers in this component */
569  .init_thread = _lmsensors_init_thread,
570  .init_component = _lmsensors_init_component,
571  .init_control_state = _lmsensors_init_control_state,
572  .start = _lmsensors_start,
573  .stop = _lmsensors_stop,
574  .read = _lmsensors_read,
575  .shutdown_thread = _lmsensors_shutdown_thread,
576  .shutdown_component = _lmsensors_shutdown_component,
577  .ctl = _lmsensors_ctl,
578  .update_control_state = _lmsensors_update_control_state,
579  .set_domain = _lmsensors_set_domain,
580  .reset = _lmsensors_reset,
581 
582  .ntv_enum_events = _lmsensors_ntv_enum_events,
583  .ntv_code_to_name = _lmsensors_ntv_code_to_name,
584  .ntv_code_to_descr = _lmsensors_ntv_code_to_descr,
585 };
char name[PAPI_MAX_STR_LEN]
Definition: papi.h:625
int _lmsensors_init_thread(hwd_context_t *ctx)
sprintf(splash[splash_line++],"\tIozone: Performance Test of File I/O\n")
#define PAPI_ENOMEM
Definition: fpapi.h:107
int _lmsensors_init_component(int cidx)
long long flags
Definition: iozone.c:12330
int _lmsensors_init_control_state(hwd_control_state_t *ctl)
#define PAPI_MAX_STR_LEN
Definition: fpapi.h:43
start
Definition: iozone.c:22736
#define PAPI_MIN_STR_LEN
Definition: fpapi.h:41
#define PAPI_ENOEVNT
Definition: fpapi.h:112
unsigned int count
static int num_events
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)
return PAPI_OK
Definition: linux-nvml.c:458
int count
Definition: iozone.c:22422
#define PAPI_DOM_OTHER
Definition: fpapi.h:23
#define PAPI_DOM_KERNEL
Definition: fpapi.h:22
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:626
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 disabled_reason[PAPI_MAX_STR_LEN]
Definition: papi.h:632
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)
long long found
Definition: libasync.c:735
free(dummyfile[xx])
static int cidx
Definition: event_info.c:40
#define PAPI_ECMP
Definition: fpapi.h:109
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
char events[MAX_EVENTS][BUFSIZ]
static _lmsensors_native_event_entry_t * lm_sensors_native_table
char description[PAPI_MAX_STR_LEN]
Definition: papi.h:628
#define PAPI_INT_SIGNAL
Definition: papi_internal.h:53
uint32_t id
Definition: linux-cuda.c:293
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:6125
int _lmsensors_reset(hwd_context_t *ctx, hwd_control_state_t *ctl)
char * name
Definition: iozone.c:23648
#define long_long
Definition: papi.h:549
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)
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
#define PAPI_DOM_USER
Definition: fpapi.h:21
int _lmsensors_shutdown_component(void)
const sensors_chip_name * name
int _lmsensors_ntv_enum_events(unsigned int *EventCode, int modifier)
#define PAPI_GRN_THR
Definition: fpapi.h:67
_lmsensors_register_t resources
_lmsensors_register_t ra_bits