PAPI  5.0.1.0
linux-lmsensors.c File Reference

This file has the source code for a component that enables PAPI-C to access hardware monitoring sensors through the libsensors library. This code will dynamically create a native events table for all the sensors that can be accesed by the libsensors library. In order to learn more about libsensors, visit: (http://www.lm-sensors.org) More...

Include dependency graph for linux-lmsensors.c:

Go to the source code of this file.

Data Structures

struct  _lmsensors_register_t
struct  _lmsensors_native_event_entry_t
struct  _lmsensors_reg_alloc_t
struct  _lmsensors_control_state_t
struct  _lmsensors_context_t

Defines

#define LM_SENSORS_MAX_COUNTERS   512
#define LM_SENSORS_REFRESHTIME   200000

Functions

static unsigned detectSensors (void)
static unsigned createNativeEvents (void)
static long_long getEventValue (unsigned event_id)
int _lmsensors_init_thread (hwd_context_t *ctx)
int _lmsensors_init_component (int cidx)
int _lmsensors_init_control_state (hwd_control_state_t *ctl)
int _lmsensors_start (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _lmsensors_stop (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _lmsensors_read (hwd_context_t *ctx, hwd_control_state_t *ctl, long_long **events, int flags)
int _lmsensors_shutdown_component (void)
int _lmsensors_shutdown_thread (hwd_context_t *ctx)
int _lmsensors_ctl (hwd_context_t *ctx, int code, _papi_int_option_t *option)
int _lmsensors_update_control_state (hwd_control_state_t *ctl, NativeInfo_t *native, int count, hwd_context_t *ctx)
int _lmsensors_set_domain (hwd_control_state_t *ctl, int domain)
int _lmsensors_reset (hwd_context_t *ctx, hwd_control_state_t *ctl)
int _lmsensors_ntv_enum_events (unsigned int *EventCode, int modifier)
int _lmsensors_ntv_code_to_name (unsigned int EventCode, char *name, int len)
int _lmsensors_ntv_code_to_descr (unsigned int EventCode, char *name, int len)

Variables

static
_lmsensors_native_event_entry_t
lm_sensors_native_table
static int num_events = 0
papi_vector_t _lmsensors_vector

Detailed Description

Author:
Daniel Lucio
Joachim Protze
Heike Jagode jagode@eecs.utk.edu

LM_SENSORS component

Tested version of lm_sensors: 3.1.1

Notes:

  • I used the ACPI and MX components to write this component. A lot of the code in this file mimics what other components already do.
  • The return values are scaled by 1000 because PAPI can not return decimals.
  • A call of PAPI_read can take up to 2 seconds while using lm_sensors!
  • Please remember that libsensors uses the GPL license.

Definition in file linux-lmsensors.c.


Define Documentation

#define LM_SENSORS_MAX_COUNTERS   512

Definition at line 46 of file linux-lmsensors.c.

#define LM_SENSORS_REFRESHTIME   200000

Definition at line 48 of file linux-lmsensors.c.


Function Documentation

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

Definition at line 400 of file linux-lmsensors.c.

{
    ( void ) ctx;
    ( void ) code;
    ( void ) option;
    return PAPI_OK;
}
int _lmsensors_init_component ( int  cidx)

Definition at line 266 of file linux-lmsensors.c.

{
    int res;
    (void) cidx;

    /* Initialize libsensors library */
    if ( ( res = sensors_init( NULL ) ) != 0 ) {
       strncpy(_lmsensors_vector.cmp_info.disabled_reason,
          "Cannot enable libsensors",PAPI_MAX_STR_LEN);
       return res;
    }

    /* Create dyanmic events table */
    num_events = detectSensors(  );
    SUBDBG("Found %d sensors\n",num_events);

    if ( ( lm_sensors_native_table =
       calloc( num_events, sizeof ( _lmsensors_native_event_entry_t )))
                   == NULL ) {
       strncpy(_lmsensors_vector.cmp_info.disabled_reason,
          "Could not malloc room",PAPI_MAX_STR_LEN);
       return PAPI_ENOMEM;
    }

    if ( ( unsigned ) num_events != createNativeEvents(  ) ) {
       strncpy(_lmsensors_vector.cmp_info.disabled_reason,
          "LM_SENSOR number mismatch",PAPI_MAX_STR_LEN);
       return PAPI_ECMP;
    }

    _lmsensors_vector.cmp_info.num_native_events=num_events;
    _lmsensors_vector.cmp_info.num_cntrs=num_events;

    return PAPI_OK;
}

Here is the call graph for this function:

Definition at line 308 of file linux-lmsensors.c.

{
    int i;

    for ( i = 0; i < num_events; i++ )
        ( ( _lmsensors_control_state_t * ) ctl )->counts[i] =
            getEventValue( i );

    ( ( _lmsensors_control_state_t * ) ctl )->lastupdate =
        PAPI_get_real_usec(  );
    return PAPI_OK;
}

Here is the call graph for this function:

Definition at line 254 of file linux-lmsensors.c.

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

Definition at line 523 of file linux-lmsensors.c.

{
    int index = EventCode;

    if (index>=0 && index<num_events) {
       strncpy( name, lm_sensors_native_table[index].description, len );
    }
    return PAPI_OK;
}
int _lmsensors_ntv_code_to_name ( unsigned int  EventCode,
char *  name,
int  len 
)

Definition at line 508 of file linux-lmsensors.c.

{
    int index = EventCode;

    if (index>=0 && index<num_events) {
       strncpy( name, lm_sensors_native_table[index].name, len );
    }

    return PAPI_OK;
}
int _lmsensors_ntv_enum_events ( unsigned int *  EventCode,
int  modifier 
)

Definition at line 476 of file linux-lmsensors.c.

{

    switch ( modifier ) {
    case PAPI_ENUM_FIRST:
        *EventCode = 0;

        return PAPI_OK;
        break;

    case PAPI_ENUM_EVENTS:
    {
        int 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 _lmsensors_read ( hwd_context_t ctx,
hwd_control_state_t ctl,
long_long **  events,
int  flags 
)

Definition at line 352 of file linux-lmsensors.c.

{
    ( void ) ctx;
    ( void ) flags;
    long long start = PAPI_get_real_usec(  );
    int i;
 
    _lmsensors_control_state_t *control=(_lmsensors_control_state_t *)ctl;

    if ( start - control->lastupdate > 200000 ) {   // cache refresh
       
       for ( i = 0; i < num_events; i++ ) {
       control->counts[i] = getEventValue( i );
       }
       control->lastupdate = PAPI_get_real_usec(  );
    }

    *events = control->counts;
    return PAPI_OK;
}

Here is the call graph for this function:

Definition at line 464 of file linux-lmsensors.c.

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

Definition at line 439 of file linux-lmsensors.c.

{
    int found = 0;
    ( void ) ctl;
    
    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 376 of file linux-lmsensors.c.

{

    /* Call the libsensors cleaning function before leaving */
    sensors_cleanup(  );

    return PAPI_OK;
}

Definition at line 386 of file linux-lmsensors.c.

{
    ( void ) ctx;

    return PAPI_OK;
}

Definition at line 326 of file linux-lmsensors.c.

{
    ( void ) ctx;
    ( void ) ctl;

    return PAPI_OK;
}

Definition at line 339 of file linux-lmsensors.c.

{
    ( void ) ctx;
    ( void ) ctl;

    return PAPI_OK;
}
int _lmsensors_update_control_state ( hwd_control_state_t ctl,
NativeInfo_t native,
int  count,
hwd_context_t ctx 
)

Definition at line 410 of file linux-lmsensors.c.

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

    for ( i = 0; i < count; i++ ) {
    index = native[i].ni_event;
    native[i].ni_position =
            lm_sensors_native_table[index].resources.selector - 1;
    }
    return PAPI_OK;
}
static unsigned createNativeEvents ( void  ) [static]

Definition at line 143 of file linux-lmsensors.c.

{
    unsigned id = 0;
    unsigned int count = 0;

    int chip_nr = 0;
    const sensors_chip_name *chip_name;

    /* component name and description */
    strcpy( _lmsensors_vector.cmp_info.short_name, "LM_SENSORS" );
    strcpy( _lmsensors_vector.cmp_info.description,
            "lm-sensors provides tools for monitoring the hardware health" );


    /* Loop through all the chips found */
    while ( ( chip_name =
              sensors_get_detected_chips( NULL, &chip_nr ) ) != NULL ) {
       int a, b;
       const sensors_feature *feature;
       const sensors_subfeature *sub;
       char chipnamestring[PAPI_MIN_STR_LEN];

       //      lm_sensors_native_table[id].count = 0;

        /* get chip name from its internal representation */
       sensors_snprintf_chip_name( chipnamestring,
                        PAPI_MIN_STR_LEN, chip_name );

       a = 0;

       /* Loop through all the features found */
       while ( ( feature = sensors_get_features( chip_name, &a ) ) ) {
          char *featurelabel;

          if ( !( featurelabel = sensors_get_label( chip_name, feature ))) {
         fprintf( stderr, "ERROR: Can't get label of feature %s!\n",
                         feature->name );
         continue;
          }

          b = 0;

          /* Loop through all the subfeatures found */
          while ((sub=sensors_get_all_subfeatures(chip_name,feature,&b))) {

             count = 0;

         /* Save native event data */
         sprintf( lm_sensors_native_table[id].name, "%s.%s.%s.%s",
              _lmsensors_vector.cmp_info.short_name,
              chipnamestring, featurelabel, sub->name );

         strncpy( lm_sensors_native_table[id].description,
              lm_sensors_native_table[id].name, PAPI_MAX_STR_LEN );

         /* The selector has to be !=0 . Starts with 1 */
         lm_sensors_native_table[id].resources.selector = id + 1;

         /* Save the actual references to this event */
         lm_sensors_native_table[id].resources.name = chip_name;
         lm_sensors_native_table[id].resources.subfeat_nr = sub->number;

         count = sub->number;

         /* increment the table index counter */
         id++;       
          }

          //   lm_sensors_native_table[id].count = count + 1;
          free( featurelabel );
       }
    }

    /* Return the number of events created */
    return id;
}

Here is the caller graph for this function:

static unsigned detectSensors ( void  ) [static]

Definition at line 114 of file linux-lmsensors.c.

{
    unsigned id = 0;
    int chip_nr = 0;
    const sensors_chip_name *chip_name;

    /* Loop through all the chips, features, subfeatures found */
    while ( ( chip_name =
              sensors_get_detected_chips( NULL, &chip_nr ) ) != NULL ) {
        int a = 0, b;
        const sensors_feature *feature;

        while ( ( feature = sensors_get_features( chip_name, &a ) ) ) {
            b = 0;
            while ( ( sensors_get_all_subfeatures( chip_name, feature,
                                                   &b ) ) ) {
                id++;
            }
        }
    }

    return id;
}

Here is the caller graph for this function:

static long_long getEventValue ( unsigned  event_id) [static]

Definition at line 227 of file linux-lmsensors.c.

{
    double value;
    int res;

    res = sensors_get_value( lm_sensors_native_table[event_id].resources.name,
                             lm_sensors_native_table[event_id].resources.
                             subfeat_nr, &value );

    if ( res < 0 ) {
        fprintf( stderr, "libsensors(): Could not read event #%d!\n",
                 event_id );
        return -1;
    }

    return ( ( long_long ) ( value * 1000 ) );
}

Here is the caller graph for this function:


Variable Documentation

int num_events = 0 [static]

Definition at line 101 of file linux-lmsensors.c.

 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines