|
Packit |
577717 |
/**
|
|
Packit |
577717 |
* @file linux-powercap.c
|
|
Packit |
577717 |
* @author Philip Vaccaro
|
|
Packit |
577717 |
* @ingroup papi_components
|
|
Packit |
577717 |
* @brief powercap component
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
* To work, the powercap kernel module must be loaded.
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#include <stdio.h>
|
|
Packit |
577717 |
#include <dirent.h>
|
|
Packit |
577717 |
#include <unistd.h>
|
|
Packit |
577717 |
#include <dirent.h>
|
|
Packit |
577717 |
#include <fcntl.h>
|
|
Packit |
577717 |
#include <string.h>
|
|
Packit |
577717 |
#include <stdint.h>
|
|
Packit |
577717 |
#include <errno.h>
|
|
Packit |
577717 |
#include <unistd.h>
|
|
Packit |
577717 |
#include <sys/types.h>
|
|
Packit |
577717 |
#include <sys/stat.h>
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Headers required by PAPI */
|
|
Packit |
577717 |
#include "papi.h"
|
|
Packit |
577717 |
#include "papi_internal.h"
|
|
Packit |
577717 |
#include "papi_vector.h"
|
|
Packit |
577717 |
#include "papi_memory.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
typedef struct _powercap_register {
|
|
Packit |
577717 |
unsigned int selector;
|
|
Packit |
577717 |
} _powercap_register_t;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
typedef struct _powercap_native_event_entry {
|
|
Packit |
577717 |
char name[PAPI_MAX_STR_LEN];
|
|
Packit |
577717 |
char units[PAPI_MIN_STR_LEN];
|
|
Packit |
577717 |
char description[PAPI_MAX_STR_LEN];
|
|
Packit |
577717 |
int socket_id;
|
|
Packit |
577717 |
int component_id;
|
|
Packit |
577717 |
int event_id;
|
|
Packit |
577717 |
int type;
|
|
Packit |
577717 |
int return_type;
|
|
Packit |
577717 |
_powercap_register_t resources;
|
|
Packit |
577717 |
} _powercap_native_event_entry_t;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
typedef struct _powercap_reg_alloc {
|
|
Packit |
577717 |
_powercap_register_t ra_bits;
|
|
Packit |
577717 |
} _powercap_reg_alloc_t;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static char read_buff[PAPI_MAX_STR_LEN];
|
|
Packit |
577717 |
static char write_buff[PAPI_MAX_STR_LEN];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int num_events=0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// package events
|
|
Packit |
577717 |
#define PKG_ENERGY 0
|
|
Packit |
577717 |
#define PKG_MAX_ENERGY_RANGE 1
|
|
Packit |
577717 |
#define PKG_MAX_POWER_A 2
|
|
Packit |
577717 |
#define PKG_POWER_LIMIT_A 3
|
|
Packit |
577717 |
#define PKG_TIME_WINDOW_A 4
|
|
Packit |
577717 |
#define PKG_MAX_POWER_B 5
|
|
Packit |
577717 |
#define PKG_POWER_LIMIT_B 6
|
|
Packit |
577717 |
#define PKG_TIME_WINDOW_B 7
|
|
Packit |
577717 |
#define PKG_ENABLED 8
|
|
Packit |
577717 |
#define PKG_NAME 9
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define PKG_NUM_EVENTS 10
|
|
Packit |
577717 |
static int pkg_events[PKG_NUM_EVENTS] = {PKG_ENERGY, PKG_MAX_ENERGY_RANGE, PKG_MAX_POWER_A, PKG_POWER_LIMIT_A, PKG_TIME_WINDOW_A, PKG_MAX_POWER_B, PKG_POWER_LIMIT_B, PKG_TIME_WINDOW_B, PKG_ENABLED, PKG_NAME};
|
|
Packit |
577717 |
static char *pkg_event_names[PKG_NUM_EVENTS] = {"ENERGY_UJ", "MAX_ENERGY_RANGE_UJ", "MAX_POWER_A_UW", "POWER_LIMIT_A_UW", "TIME_WINDOW_A_US", "MAX_POWER_B_UW", "POWER_LIMIT_B_UW", "TIME_WINDOW_B", "ENABLED", "NAME"};
|
|
Packit |
577717 |
static char *pkg_sys_names[PKG_NUM_EVENTS] = {"energy_uj", "max_energy_range_uj", "constraint_0_max_power_uw", "constraint_0_power_limit_uw", "constraint_0_time_window_us", "constraint_1_max_power_uw", "constraint_1_power_limit_uw", "constraint_1_time_window_us", "enabled", "name"};
|
|
Packit |
577717 |
static mode_t pkg_sys_flags[PKG_NUM_EVENTS] = {O_RDONLY, O_RDONLY, O_RDONLY, O_RDWR, O_RDONLY, O_RDONLY, O_RDWR, O_RDONLY, O_RDONLY, O_RDONLY};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// non-package events
|
|
Packit |
577717 |
#define COMPONENT_ENERGY 10
|
|
Packit |
577717 |
#define COMPONENT_MAX_ENERGY_RANGE 11
|
|
Packit |
577717 |
#define COMPONENT_MAX_POWER_A 12
|
|
Packit |
577717 |
#define COMPONENT_POWER_LIMIT_A 13
|
|
Packit |
577717 |
#define COMPONENT_TIME_WINDOW_A 14
|
|
Packit |
577717 |
#define COMPONENT_ENABLED 15
|
|
Packit |
577717 |
#define COMPONENT_NAME 16
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define COMPONENT_NUM_EVENTS 7
|
|
Packit |
577717 |
static int component_events[COMPONENT_NUM_EVENTS] = {COMPONENT_ENERGY, COMPONENT_MAX_ENERGY_RANGE, COMPONENT_MAX_POWER_A, COMPONENT_POWER_LIMIT_A, COMPONENT_TIME_WINDOW_A, COMPONENT_ENABLED, COMPONENT_NAME};
|
|
Packit |
577717 |
static char *component_event_names[COMPONENT_NUM_EVENTS] = {"ENERGY_UJ", "MAX_ENERGY_RANGE_UJ", "MAX_POWER_A_UW", "POWER_LIMIT_A_UW", "TIME_WINDOW_A_US", "ENABLED", "NAME"};
|
|
Packit |
577717 |
static char *component_sys_names[COMPONENT_NUM_EVENTS] = {"energy_uj", "max_energy_range_uj", "constraint_0_max_power_uw", "constraint_0_power_limit_uw", "constraint_0_time_window_us", "enabled", "name"};
|
|
Packit |
577717 |
static mode_t component_sys_flags[COMPONENT_NUM_EVENTS] = {O_RDONLY, O_RDONLY, O_RDONLY, O_RDWR, O_RDONLY, O_RDONLY, O_RDONLY};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define POWERCAP_MAX_COUNTERS (2 * (PKG_NUM_EVENTS + (3 * COMPONENT_NUM_EVENTS)))
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static _powercap_native_event_entry_t powercap_ntv_events[(2 * (PKG_NUM_EVENTS + (3 * COMPONENT_NUM_EVENTS)))];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int event_fds[POWERCAP_MAX_COUNTERS];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
typedef struct _powercap_control_state {
|
|
Packit |
577717 |
long long count[POWERCAP_MAX_COUNTERS];
|
|
Packit |
577717 |
long long which_counter[POWERCAP_MAX_COUNTERS];
|
|
Packit |
577717 |
long long lastupdate;
|
|
Packit |
577717 |
} _powercap_control_state_t;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
typedef struct _powercap_context {
|
|
Packit |
577717 |
long long start_value[POWERCAP_MAX_COUNTERS];
|
|
Packit |
577717 |
_powercap_control_state_t state;
|
|
Packit |
577717 |
} _powercap_context_t;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
papi_vector_t _powercap_vector;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/***************************************************************************/
|
|
Packit |
577717 |
/****** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT *******/
|
|
Packit |
577717 |
/***************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Null terminated version of strncpy */
|
|
Packit |
577717 |
static char * _local_strlcpy( char *dst, const char *src, size_t size )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
char *retval = strncpy( dst, src, size );
|
|
Packit |
577717 |
if ( size>0 ) dst[size-1] = '\0';
|
|
Packit |
577717 |
return( retval );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static long long read_powercap_value( int index )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int sz = pread(event_fds[index], read_buff, PAPI_MAX_STR_LEN, 0);
|
|
Packit |
577717 |
read_buff[sz] = '\0';
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return atoll(read_buff);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int write_powercap_value( int index, long long value )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
snprintf(write_buff, sizeof(write_buff), "%lld", value);
|
|
Packit |
577717 |
int sz = pwrite(event_fds[index], write_buff, PAPI_MAX_STR_LEN, 0);
|
|
Packit |
577717 |
if(sz == -1) {
|
|
Packit |
577717 |
perror("Error in pwrite(): ");
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************* PAPI Functions **********************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* This is called whenever a thread is initialized
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int _powercap_init_thread( hwd_context_t *ctx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Called when PAPI process is initialized (i.e. PAPI_library_init)
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int _powercap_init_component( int cidx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int num_sockets = -1;
|
|
Packit |
577717 |
int s = -1, e = -1, c = -1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
char events_dir[128];
|
|
Packit |
577717 |
char event_path[128];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
DIR *events;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// get hw info
|
|
Packit |
577717 |
const PAPI_hw_info_t *hw_info;
|
|
Packit |
577717 |
hw_info=&( _papi_hwi_system_info.hw_info );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// check if intel processor
|
|
Packit |
577717 |
if ( hw_info->vendor!=PAPI_VENDOR_INTEL ) {
|
|
Packit |
577717 |
strncpy(_powercap_vector.cmp_info.disabled_reason, "Not an Intel processor", PAPI_MAX_STR_LEN);
|
|
Packit |
577717 |
return PAPI_ENOSUPP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// store number of sockets for adding events
|
|
Packit |
577717 |
num_sockets = hw_info->sockets;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
num_events = 0;
|
|
Packit |
577717 |
for(s = 0; s < num_sockets; s++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// compose string of a pkg directory path
|
|
Packit |
577717 |
snprintf(events_dir, sizeof(events_dir), "/sys/class/powercap/intel-rapl:%d/", s);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// open directory to make sure it exists
|
|
Packit |
577717 |
events = opendir(events_dir);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// not a valid pkg/component directory so continue
|
|
Packit |
577717 |
if (events == NULL) { continue; }
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// loop through pkg events and create powercap event entries
|
|
Packit |
577717 |
for (e = 0; e < PKG_NUM_EVENTS; e++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// compose string to individual event
|
|
Packit |
577717 |
snprintf(event_path, sizeof(event_path), "%s%s", events_dir, pkg_sys_names[e]);
|
|
Packit |
577717 |
// not a valid pkg event path so continue
|
|
Packit |
577717 |
if (access(event_path, F_OK) == -1) { continue; }
|
|
Packit |
577717 |
|
|
Packit |
577717 |
snprintf(powercap_ntv_events[num_events].name, sizeof(powercap_ntv_events[num_events].name), "%s:ZONE%d", pkg_event_names[e], s);
|
|
Packit |
577717 |
//snprintf(powercap_ntv_events[num_events].description, sizeof(powercap_ntv_events[num_events].name), "%s:ZONE%d", pkg_event_names[e], s);
|
|
Packit |
577717 |
//snprintf(powercap_ntv_events[num_events].units, sizeof(powercap_ntv_events[num_events].name), "%s:ZONE%d", pkg_event_names[e], s);
|
|
Packit |
577717 |
powercap_ntv_events[num_events].return_type = PAPI_DATATYPE_UINT64;
|
|
Packit |
577717 |
powercap_ntv_events[num_events].type = pkg_events[e];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
powercap_ntv_events[num_events].resources.selector = num_events + 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
event_fds[num_events] = open(event_path, O_SYNC|pkg_sys_flags[e]);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if(powercap_ntv_events[num_events].type == PKG_NAME) {
|
|
Packit |
577717 |
int sz = pread(event_fds[num_events], read_buff, PAPI_MAX_STR_LEN, 0);
|
|
Packit |
577717 |
read_buff[sz] = '\0';
|
|
Packit |
577717 |
snprintf(powercap_ntv_events[num_events].description, sizeof(powercap_ntv_events[num_events].description), "%s", read_buff);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
num_events++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// reset component count for each socket
|
|
Packit |
577717 |
c = 0;
|
|
Packit |
577717 |
snprintf(events_dir, sizeof(events_dir), "/sys/class/powercap/intel-rapl:%d:%d/", s, c);
|
|
Packit |
577717 |
while((events = opendir(events_dir)) != NULL) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// loop through pkg events and create powercap event entries
|
|
Packit |
577717 |
for (e = 0; e < COMPONENT_NUM_EVENTS; e++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// compose string to individual event
|
|
Packit |
577717 |
snprintf(event_path, sizeof(event_path), "%s%s", events_dir, component_sys_names[e]);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// not a valid pkg event path so continue
|
|
Packit |
577717 |
if (access(event_path, F_OK) == -1) { continue; }
|
|
Packit |
577717 |
|
|
Packit |
577717 |
snprintf(powercap_ntv_events[num_events].name, sizeof(powercap_ntv_events[num_events].name), "%s:ZONE%d_SUBZONE%d", component_event_names[e], s, c);
|
|
Packit |
577717 |
//snprintf(powercap_ntv_events[num_events].description, sizeof(powercap_ntv_events[num_events].name), "%s:ZONE%d_SUBZONE%d", component_event_names[e], s, c);
|
|
Packit |
577717 |
//snprintf(powercap_ntv_events[num_events].units, sizeof(powercap_ntv_events[num_events].name), "%s:ZONE%d_SUBZONE%d", component_event_names[e], s, c);
|
|
Packit |
577717 |
powercap_ntv_events[num_events].return_type = PAPI_DATATYPE_UINT64;
|
|
Packit |
577717 |
powercap_ntv_events[num_events].type = component_events[e];
|
|
Packit |
577717 |
|
|
Packit |
577717 |
powercap_ntv_events[num_events].resources.selector = num_events + 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
event_fds[num_events] = open(event_path, O_SYNC|component_sys_flags[e]);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if(powercap_ntv_events[num_events].type == COMPONENT_NAME) {
|
|
Packit |
577717 |
int sz = pread(event_fds[num_events], read_buff, PAPI_MAX_STR_LEN, 0);
|
|
Packit |
577717 |
read_buff[sz] = '\0';
|
|
Packit |
577717 |
snprintf(powercap_ntv_events[num_events].description, sizeof(powercap_ntv_events[num_events].description), "%s", read_buff);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
num_events++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// test for next component
|
|
Packit |
577717 |
c++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
// compose string of an pkg directory path
|
|
Packit |
577717 |
snprintf(events_dir, sizeof(events_dir), "/sys/class/powercap/intel-rapl:%d:%d/", s, c);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Export the total number of events available */
|
|
Packit |
577717 |
_powercap_vector.cmp_info.num_native_events = num_events;
|
|
Packit |
577717 |
_powercap_vector.cmp_info.num_cntrs = num_events;
|
|
Packit |
577717 |
_powercap_vector.cmp_info.num_mpx_cntrs = num_events;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Export the component id */
|
|
Packit |
577717 |
_powercap_vector.cmp_info.CmpIdx = cidx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Control of counters (Reading/Writing/Starting/Stopping/Setup)
|
|
Packit |
577717 |
* functions
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int _powercap_init_control_state( hwd_control_state_t *ctl )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
_powercap_control_state_t* control = ( _powercap_control_state_t* ) ctl;
|
|
Packit |
577717 |
memset( control, 0, sizeof ( _powercap_control_state_t ) );
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int _powercap_start( hwd_context_t *ctx, hwd_control_state_t *ctl )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
_powercap_context_t* context = ( _powercap_context_t* ) ctx;
|
|
Packit |
577717 |
(void) ctl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int b;
|
|
Packit |
577717 |
for( b = 0; b < num_events; b++ ) {
|
|
Packit |
577717 |
context->start_value[b]=read_powercap_value(b);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int _powercap_stop( hwd_context_t *ctx, hwd_control_state_t *ctl )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
(void) ctx;
|
|
Packit |
577717 |
_powercap_control_state_t* control = ( _powercap_control_state_t* ) ctl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int c;
|
|
Packit |
577717 |
for( c = 0; c < num_events; c++ ) {
|
|
Packit |
577717 |
control->count[c]=read_powercap_value(c);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Shutdown a thread */
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_powercap_shutdown_thread( hwd_context_t *ctx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
SUBDBG( "Enter\n" );
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_powercap_read( hwd_context_t *ctx, hwd_control_state_t *ctl,
|
|
Packit |
577717 |
long long **events, int flags )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
(void) ctx;
|
|
Packit |
577717 |
(void) flags;
|
|
Packit |
577717 |
_powercap_control_state_t* control = ( _powercap_control_state_t* ) ctl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
control->count[i]=read_powercap_value(control->which_counter[i]);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
*events = ( ( _powercap_control_state_t* ) ctl )->count;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int _powercap_write( hwd_context_t * ctx, hwd_control_state_t * ctl, long long *values )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
/* write values */
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
_powercap_control_state_t *control = ( _powercap_control_state_t * ) ctl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
if( (powercap_ntv_events[control->which_counter[i]].type == PKG_POWER_LIMIT_A) || (powercap_ntv_events[control->which_counter[i]].type == PKG_POWER_LIMIT_B) ) {
|
|
Packit |
577717 |
write_powercap_value(control->which_counter[i], values[i]);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Clean up what was setup in powercap_init_component().
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int _powercap_shutdown_component( void )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Read counters into expected slot */
|
|
Packit |
577717 |
for(i=0;i
|
|
Packit |
577717 |
close(event_fds[i]);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This function sets various options in the component. The valid
|
|
Packit |
577717 |
* codes being passed in are PAPI_SET_DEFDOM, PAPI_SET_DOMAIN,
|
|
Packit |
577717 |
* PAPI_SETDEFGRN, PAPI_SET_GRANUL and PAPI_SET_INHERIT
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_powercap_ctl( hwd_context_t *ctx, int code, _papi_int_option_t *option )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
SUBDBG( "Enter: ctx: %p\n", ctx );
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
( void ) code;
|
|
Packit |
577717 |
( void ) option;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int _powercap_update_control_state( hwd_control_state_t *ctl,
|
|
Packit |
577717 |
NativeInfo_t *native, int count,
|
|
Packit |
577717 |
hwd_context_t *ctx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
(void) ctx;
|
|
Packit |
577717 |
int i, index;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_powercap_control_state_t* control = ( _powercap_control_state_t* ) ctl;
|
|
Packit |
577717 |
if (count==0) return PAPI_OK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for( i = 0; i < count; i++ ) {
|
|
Packit |
577717 |
index = native[i].ni_event;
|
|
Packit |
577717 |
control->which_counter[i]=index;
|
|
Packit |
577717 |
native[i].ni_position = i;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int _powercap_set_domain( hwd_control_state_t *ctl, int domain )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
( void ) ctl;
|
|
Packit |
577717 |
if ( PAPI_DOM_ALL != domain )
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int _powercap_reset( hwd_context_t *ctx, hwd_control_state_t *ctl )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
( void ) ctl;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Native Event functions
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int _powercap_ntv_enum_events( unsigned int *EventCode, int modifier )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int index;
|
|
Packit |
577717 |
switch ( modifier ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PAPI_ENUM_FIRST:
|
|
Packit |
577717 |
*EventCode = 0;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
case PAPI_ENUM_EVENTS:index = *EventCode;
|
|
Packit |
577717 |
if (index < num_events - 1) {
|
|
Packit |
577717 |
*EventCode = *EventCode + 1;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
default:return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int _powercap_ntv_code_to_name( unsigned int EventCode, char *name, int len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int index = EventCode & PAPI_NATIVE_AND_MASK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( index >= 0 && index < num_events ) {
|
|
Packit |
577717 |
_local_strlcpy( name, powercap_ntv_events[index].name, len );
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int _powercap_ntv_code_to_descr( unsigned int EventCode, char *name, int len )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int index = EventCode;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( index < 0 && index >= num_events )
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
_local_strlcpy( name, powercap_ntv_events[index].description, len );
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int _powercap_ntv_code_to_info( unsigned int EventCode, PAPI_event_info_t *info )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int index = EventCode;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( index < 0 || index >= num_events )
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_local_strlcpy( info->symbol, powercap_ntv_events[index].name, sizeof( info->symbol ));
|
|
Packit |
577717 |
_local_strlcpy( info->long_descr, powercap_ntv_events[index].description, sizeof( info->long_descr ) );
|
|
Packit |
577717 |
_local_strlcpy( info->units, powercap_ntv_events[index].units, sizeof( info->units ) );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
info->data_type = powercap_ntv_events[index].return_type;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
papi_vector_t _powercap_vector = {
|
|
Packit |
577717 |
.cmp_info = { /* (unspecified values are initialized to 0) */
|
|
Packit |
577717 |
.name = "powercap",
|
|
Packit |
577717 |
.short_name = "powercap",
|
|
Packit |
577717 |
.description = "Linux powercap energy measurements",
|
|
Packit |
577717 |
.version = "5.3.0",
|
|
Packit |
577717 |
.default_domain = PAPI_DOM_ALL,
|
|
Packit |
577717 |
.default_granularity = PAPI_GRN_SYS,
|
|
Packit |
577717 |
.available_granularities = PAPI_GRN_SYS,
|
|
Packit |
577717 |
.hardware_intr_sig = PAPI_INT_SIGNAL,
|
|
Packit |
577717 |
.available_domains = PAPI_DOM_ALL,
|
|
Packit |
577717 |
},
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* sizes of framework-opaque component-private structures */
|
|
Packit |
577717 |
.size = {
|
|
Packit |
577717 |
.context = sizeof ( _powercap_context_t ),
|
|
Packit |
577717 |
.control_state = sizeof ( _powercap_control_state_t ),
|
|
Packit |
577717 |
.reg_value = sizeof ( _powercap_register_t ),
|
|
Packit |
577717 |
.reg_alloc = sizeof ( _powercap_reg_alloc_t ),
|
|
Packit |
577717 |
},
|
|
Packit |
577717 |
/* function pointers in this component */
|
|
Packit |
577717 |
.init_thread = _powercap_init_thread,
|
|
Packit |
577717 |
.init_component = _powercap_init_component,
|
|
Packit |
577717 |
.init_control_state = _powercap_init_control_state,
|
|
Packit |
577717 |
.update_control_state = _powercap_update_control_state,
|
|
Packit |
577717 |
.start = _powercap_start,
|
|
Packit |
577717 |
.stop = _powercap_stop,
|
|
Packit |
577717 |
.read = _powercap_read,
|
|
Packit |
577717 |
.write = _powercap_write,
|
|
Packit |
577717 |
.shutdown_thread = _powercap_shutdown_thread,
|
|
Packit |
577717 |
.shutdown_component = _powercap_shutdown_component,
|
|
Packit |
577717 |
.ctl = _powercap_ctl,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.set_domain = _powercap_set_domain,
|
|
Packit |
577717 |
.reset = _powercap_reset,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.ntv_enum_events = _powercap_ntv_enum_events,
|
|
Packit |
577717 |
.ntv_code_to_name = _powercap_ntv_code_to_name,
|
|
Packit |
577717 |
.ntv_code_to_descr = _powercap_ntv_code_to_descr,
|
|
Packit |
577717 |
.ntv_code_to_info = _powercap_ntv_code_to_info,
|
|
Packit |
577717 |
};
|