|
Packit |
577717 |
#include <string.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 |
#include "linux-coretemp.h"
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* this is what I found on my core2 machine
|
|
Packit |
577717 |
* but I have not explored this widely yet*/
|
|
Packit |
577717 |
#define REFRESH_LAT 4000
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define INVALID_RESULT -1000000L
|
|
Packit |
577717 |
|
|
Packit |
577717 |
papi_vector_t _coretemp_vector;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* temporary event */
|
|
Packit |
577717 |
struct temp_event {
|
|
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 |
char location[PAPI_MAX_STR_LEN];
|
|
Packit |
577717 |
char path[PATH_MAX];
|
|
Packit |
577717 |
int stone;
|
|
Packit |
577717 |
long count;
|
|
Packit |
577717 |
struct temp_event *next;
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static CORETEMP_native_event_entry_t * _coretemp_native_events;
|
|
Packit |
577717 |
static int num_events = 0;
|
|
Packit |
577717 |
static int is_initialized = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/***************************************************************************/
|
|
Packit |
577717 |
/****** BEGIN FUNCTIONS USED INTERNALLY SPECIFIC TO THIS COMPONENT *******/
|
|
Packit |
577717 |
/***************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static struct temp_event* root = NULL;
|
|
Packit |
577717 |
static struct temp_event *last = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
insert_in_list(char *name, char *units,
|
|
Packit |
577717 |
char *description, char *filename) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
struct temp_event *temp;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* new_event path, events->d_name */
|
|
Packit |
577717 |
temp = (struct temp_event *) papi_calloc(1, sizeof(struct temp_event));
|
|
Packit |
577717 |
if (temp==NULL) {
|
|
Packit |
577717 |
PAPIERROR("out of memory!");
|
|
Packit |
577717 |
/* We should also free any previously allocated data */
|
|
Packit |
577717 |
return PAPI_ENOMEM;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
temp->next = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (root == NULL) {
|
|
Packit |
577717 |
root = temp;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else if (last) {
|
|
Packit |
577717 |
last->next = temp;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
/* Because this is a function, it is possible */
|
|
Packit |
577717 |
/* we are called with root!=NULL but no last */
|
|
Packit |
577717 |
/* so add this to keep coverity happy */
|
|
Packit |
577717 |
free(temp);
|
|
Packit |
577717 |
PAPIERROR("This shouldn't be possible\n");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_ECMP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
last = temp;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
snprintf(temp->name, PAPI_MAX_STR_LEN, "%s", name);
|
|
Packit |
577717 |
snprintf(temp->units, PAPI_MIN_STR_LEN, "%s", units);
|
|
Packit |
577717 |
snprintf(temp->description, PAPI_MAX_STR_LEN, "%s", description);
|
|
Packit |
577717 |
snprintf(temp->path, PATH_MAX, "%s", filename);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* find all coretemp information reported by the kernel
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
generateEventList(char *base_dir)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
char path[PATH_MAX],filename[PATH_MAX];
|
|
Packit |
577717 |
char modulename[PAPI_MIN_STR_LEN],
|
|
Packit |
577717 |
location[PAPI_MIN_STR_LEN],
|
|
Packit |
577717 |
units[PAPI_MIN_STR_LEN],
|
|
Packit |
577717 |
description[PAPI_MAX_STR_LEN],
|
|
Packit |
577717 |
name[PAPI_MAX_STR_LEN];
|
|
Packit |
577717 |
DIR *dir,*d;
|
|
Packit |
577717 |
FILE *fff;
|
|
Packit |
577717 |
int count = 0;
|
|
Packit |
577717 |
struct dirent *hwmonx;
|
|
Packit |
577717 |
int i,pathnum;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
#define NUM_PATHS 2
|
|
Packit |
577717 |
char paths[NUM_PATHS][PATH_MAX]={
|
|
Packit |
577717 |
"device","."
|
|
Packit |
577717 |
};
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Open "/sys/class/hwmon" */
|
|
Packit |
577717 |
dir = opendir(base_dir);
|
|
Packit |
577717 |
if ( dir == NULL ) {
|
|
Packit |
577717 |
SUBDBG("Can't find %s, are you sure the coretemp module is loaded?\n",
|
|
Packit |
577717 |
base_dir);
|
|
Packit |
577717 |
return 0;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Iterate each /sys/class/hwmonX/device directory */
|
|
Packit |
577717 |
while( (hwmonx = readdir(dir) ) ) {
|
|
Packit |
577717 |
if ( !strncmp("hwmon", hwmonx->d_name, 5) ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Found a hwmon directory */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Sometimes the files are in ./, sometimes in device/ */
|
|
Packit |
577717 |
for(pathnum=0;pathnum
|
|
Packit |
577717 |
|
|
Packit |
577717 |
snprintf(path, PATH_MAX, "%s/%s/%s",
|
|
Packit |
577717 |
base_dir, hwmonx->d_name,paths[pathnum]);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
SUBDBG("Trying to open %s\n",path);
|
|
Packit |
577717 |
d = opendir(path);
|
|
Packit |
577717 |
if (d==NULL) {
|
|
Packit |
577717 |
continue;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Get the name of the module */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
snprintf(filename, PAPI_MAX_STR_LEN, "%s/name",path);
|
|
Packit |
577717 |
fff=fopen(filename,"r");
|
|
Packit |
577717 |
if (fff==NULL) {
|
|
Packit |
577717 |
snprintf(modulename, PAPI_MIN_STR_LEN, "Unknown");
|
|
Packit |
577717 |
} else {
|
|
Packit |
577717 |
if (fgets(modulename,PAPI_MIN_STR_LEN,fff)!=NULL) {
|
|
Packit |
577717 |
modulename[strlen(modulename)-1]='\0';
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
fclose(fff);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
SUBDBG("Found module %s\n",modulename);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/******************************************************/
|
|
Packit |
577717 |
/* Try handling all events starting with in (voltage) */
|
|
Packit |
577717 |
/******************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* arbitrary maximum */
|
|
Packit |
577717 |
/* the problem is the numbering can be sparse */
|
|
Packit |
577717 |
/* should probably go back to dirent listing */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i<32;i++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Try looking for a location label */
|
|
Packit |
577717 |
snprintf(filename, PAPI_MAX_STR_LEN, "%s/in%d_label",
|
|
Packit |
577717 |
path,i);
|
|
Packit |
577717 |
fff=fopen(filename,"r");
|
|
Packit |
577717 |
if (fff==NULL) {
|
|
Packit |
577717 |
strncpy(location,"?",PAPI_MIN_STR_LEN);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
|
|
Packit |
577717 |
location[strlen(location)-1]='\0';
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
fclose(fff);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Look for input temperature */
|
|
Packit |
577717 |
snprintf(filename, PAPI_MAX_STR_LEN, "%s/in%d_input",
|
|
Packit |
577717 |
path,i);
|
|
Packit |
577717 |
fff=fopen(filename,"r");
|
|
Packit |
577717 |
if (fff==NULL) continue;
|
|
Packit |
577717 |
fclose(fff);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
snprintf(name, PAPI_MAX_STR_LEN, "%s:in%i_input",
|
|
Packit |
577717 |
hwmonx->d_name, i);
|
|
Packit |
577717 |
snprintf(units, PAPI_MIN_STR_LEN, "V");
|
|
Packit |
577717 |
snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
|
|
Packit |
577717 |
units,modulename,
|
|
Packit |
577717 |
location);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
|
|
Packit |
577717 |
goto done_error;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
count++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************/
|
|
Packit |
577717 |
/* Try handling all events starting with temp (temperature) */
|
|
Packit |
577717 |
/************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i<32;i++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Try looking for a location label */
|
|
Packit |
577717 |
snprintf(filename, PAPI_MAX_STR_LEN, "%s/temp%d_label",
|
|
Packit |
577717 |
path,i);
|
|
Packit |
577717 |
fff=fopen(filename,"r");
|
|
Packit |
577717 |
if (fff==NULL) {
|
|
Packit |
577717 |
strncpy(location,"?",PAPI_MIN_STR_LEN);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
|
|
Packit |
577717 |
location[strlen(location)-1]='\0';
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
fclose(fff);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Look for input temperature */
|
|
Packit |
577717 |
snprintf(filename, PAPI_MAX_STR_LEN, "%s/temp%d_input",
|
|
Packit |
577717 |
path,i);
|
|
Packit |
577717 |
fff=fopen(filename,"r");
|
|
Packit |
577717 |
if (fff==NULL) continue;
|
|
Packit |
577717 |
fclose(fff);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
snprintf(name, PAPI_MAX_STR_LEN, "%s:temp%i_input",
|
|
Packit |
577717 |
hwmonx->d_name, i);
|
|
Packit |
577717 |
snprintf(units, PAPI_MIN_STR_LEN, "degrees C");
|
|
Packit |
577717 |
snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
|
|
Packit |
577717 |
units,modulename,
|
|
Packit |
577717 |
location);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
|
|
Packit |
577717 |
goto done_error;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
count++;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/************************************************************/
|
|
Packit |
577717 |
/* Try handling all events starting with fan (fan) */
|
|
Packit |
577717 |
/************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for(i=0;i<32;i++) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Try looking for a location label */
|
|
Packit |
577717 |
snprintf(filename, PAPI_MAX_STR_LEN, "%s/fan%d_label",
|
|
Packit |
577717 |
path,i);
|
|
Packit |
577717 |
fff=fopen(filename,"r");
|
|
Packit |
577717 |
if (fff==NULL) {
|
|
Packit |
577717 |
strncpy(location,"?",PAPI_MIN_STR_LEN);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
if (fgets(location,PAPI_MIN_STR_LEN,fff)!=NULL) {
|
|
Packit |
577717 |
location[strlen(location)-1]='\0';
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
fclose(fff);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Look for input fan */
|
|
Packit |
577717 |
snprintf(filename, PAPI_MAX_STR_LEN, "%s/fan%d_input",
|
|
Packit |
577717 |
path,i);
|
|
Packit |
577717 |
fff=fopen(filename,"r");
|
|
Packit |
577717 |
if (fff==NULL) continue;
|
|
Packit |
577717 |
fclose(fff);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
snprintf(name, PAPI_MAX_STR_LEN, "%s:fan%i_input",
|
|
Packit |
577717 |
hwmonx->d_name, i);
|
|
Packit |
577717 |
snprintf(units, PAPI_MIN_STR_LEN, "RPM");
|
|
Packit |
577717 |
snprintf(description, PAPI_MAX_STR_LEN, "%s, %s module, label %s",
|
|
Packit |
577717 |
units,modulename,
|
|
Packit |
577717 |
location);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (insert_in_list(name,units,description,filename)!=PAPI_OK) {
|
|
Packit |
577717 |
goto done_error;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
count++;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
closedir(d);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
closedir(dir);
|
|
Packit |
577717 |
return count;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
done_error:
|
|
Packit |
577717 |
closedir(d);
|
|
Packit |
577717 |
closedir(dir);
|
|
Packit |
577717 |
return PAPI_ECMP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static long long
|
|
Packit |
577717 |
getEventValue( int index )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
char buf[PAPI_MAX_STR_LEN];
|
|
Packit |
577717 |
FILE* fp;
|
|
Packit |
577717 |
long result;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (_coretemp_native_events[index].stone) {
|
|
Packit |
577717 |
return _coretemp_native_events[index].value;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
fp = fopen(_coretemp_native_events[index].path, "r");
|
|
Packit |
577717 |
if (fp==NULL) {
|
|
Packit |
577717 |
return INVALID_RESULT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (fgets(buf, PAPI_MAX_STR_LEN, fp)==NULL) {
|
|
Packit |
577717 |
result=INVALID_RESULT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
else {
|
|
Packit |
577717 |
result=strtoll(buf, NULL, 10);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
fclose(fp);
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return result;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*****************************************************************************
|
|
Packit |
577717 |
******************* BEGIN PAPI's COMPONENT REQUIRED FUNCTIONS *************
|
|
Packit |
577717 |
*****************************************************************************/
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* This is called whenever a thread is initialized
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_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 |
|
|
Packit |
577717 |
/* Initialize hardware counters, setup the function vector table
|
|
Packit |
577717 |
* and get hardware information, this routine is called when the
|
|
Packit |
577717 |
* PAPI process is initialized (IE PAPI_library_init)
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_init_component( int cidx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i = 0;
|
|
Packit |
577717 |
struct temp_event *t,*last;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( is_initialized )
|
|
Packit |
577717 |
return (PAPI_OK );
|
|
Packit |
577717 |
|
|
Packit |
577717 |
is_initialized = 1;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This is the prefered method, all coretemp sensors are symlinked here
|
|
Packit |
577717 |
* see $(kernel_src)/Documentation/hwmon/sysfs-interface */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
num_events = generateEventList("/sys/class/hwmon");
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( num_events < 0 ) {
|
|
Packit |
577717 |
strncpy(_coretemp_vector.cmp_info.disabled_reason,
|
|
Packit |
577717 |
"Cannot open /sys/class/hwmon",PAPI_MAX_STR_LEN);
|
|
Packit |
577717 |
return PAPI_ENOCMP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( num_events == 0 ) {
|
|
Packit |
577717 |
strncpy(_coretemp_vector.cmp_info.disabled_reason,
|
|
Packit |
577717 |
"No coretemp events found",PAPI_MAX_STR_LEN);
|
|
Packit |
577717 |
return PAPI_ENOCMP;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
t = root;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
_coretemp_native_events = (CORETEMP_native_event_entry_t*)
|
|
Packit |
577717 |
papi_calloc(num_events, sizeof(CORETEMP_native_event_entry_t));
|
|
Packit |
577717 |
|
|
Packit |
577717 |
do {
|
|
Packit |
577717 |
strncpy(_coretemp_native_events[i].name,t->name,PAPI_MAX_STR_LEN);
|
|
Packit |
577717 |
_coretemp_native_events[i].name[PAPI_MAX_STR_LEN-1] = '\0';
|
|
Packit |
577717 |
strncpy(_coretemp_native_events[i].path,t->path,PATH_MAX);
|
|
Packit |
577717 |
_coretemp_native_events[i].path[PATH_MAX-1] = '\0';
|
|
Packit |
577717 |
strncpy(_coretemp_native_events[i].units,t->units,PAPI_MIN_STR_LEN);
|
|
Packit |
577717 |
_coretemp_native_events[i].units[PAPI_MIN_STR_LEN-1] = '\0';
|
|
Packit |
577717 |
strncpy(_coretemp_native_events[i].description,t->description,PAPI_MAX_STR_LEN);
|
|
Packit |
577717 |
_coretemp_native_events[i].description[PAPI_MAX_STR_LEN-1] = '\0';
|
|
Packit |
577717 |
_coretemp_native_events[i].stone = 0;
|
|
Packit |
577717 |
_coretemp_native_events[i].resources.selector = i + 1;
|
|
Packit |
577717 |
last = t;
|
|
Packit |
577717 |
t = t->next;
|
|
Packit |
577717 |
papi_free(last);
|
|
Packit |
577717 |
i++;
|
|
Packit |
577717 |
} while (t != NULL);
|
|
Packit |
577717 |
root = NULL;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Export the total number of events available */
|
|
Packit |
577717 |
_coretemp_vector.cmp_info.num_native_events = num_events;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Export the component id */
|
|
Packit |
577717 |
_coretemp_vector.cmp_info.CmpIdx = cidx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
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
|
|
Packit |
577717 |
_coretemp_init_control_state( hwd_control_state_t * ctl)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
CORETEMP_control_state_t *coretemp_ctl = (CORETEMP_control_state_t *) ctl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i=0; i < num_events; i++ ) {
|
|
Packit |
577717 |
coretemp_ctl->counts[i] = getEventValue(i);
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Set last access time for caching results */
|
|
Packit |
577717 |
coretemp_ctl->lastupdate = PAPI_get_real_usec();
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_start( hwd_context_t *ctx, hwd_control_state_t *ctl)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
( void ) ctl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_read( hwd_context_t *ctx, hwd_control_state_t *ctl,
|
|
Packit |
577717 |
long long ** events, int flags)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
(void) flags;
|
|
Packit |
577717 |
(void) ctx;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
CORETEMP_control_state_t* control = (CORETEMP_control_state_t*) ctl;
|
|
Packit |
577717 |
long long now = PAPI_get_real_usec();
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Only read the values from the kernel if enough time has passed */
|
|
Packit |
577717 |
/* since the last read. Otherwise return cached values. */
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( now - control->lastupdate > REFRESH_LAT ) {
|
|
Packit |
577717 |
for ( i = 0; i < num_events; i++ ) {
|
|
Packit |
577717 |
control->counts[i] = getEventValue( i );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
control->lastupdate = now;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Pass back a pointer to our results */
|
|
Packit |
577717 |
*events = control->counts;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_stop( hwd_context_t *ctx, hwd_control_state_t *ctl )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
(void) ctx;
|
|
Packit |
577717 |
/* read values */
|
|
Packit |
577717 |
CORETEMP_control_state_t* control = (CORETEMP_control_state_t*) ctl;
|
|
Packit |
577717 |
int i;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < num_events; i++ ) {
|
|
Packit |
577717 |
control->counts[i] = getEventValue( i );
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* Shutdown a thread */
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_shutdown_thread( hwd_context_t * ctx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Clean up what was setup in coretemp_init_component().
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_shutdown_component( )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
if ( is_initialized ) {
|
|
Packit |
577717 |
is_initialized = 0;
|
|
Packit |
577717 |
papi_free(_coretemp_native_events);
|
|
Packit |
577717 |
_coretemp_native_events = NULL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* This function sets various options in the component
|
|
Packit |
577717 |
* The valid codes being passed in are PAPI_SET_DEFDOM,
|
|
Packit |
577717 |
* PAPI_SET_DOMAIN, PAPI_SETDEFGRN, PAPI_SET_GRANUL * and PAPI_SET_INHERIT
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_ctl( hwd_context_t *ctx, int code, _papi_int_option_t *option )
|
|
Packit |
577717 |
{
|
|
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
|
|
Packit |
577717 |
_coretemp_update_control_state( hwd_control_state_t *ptr,
|
|
Packit |
577717 |
NativeInfo_t * native, int count,
|
|
Packit |
577717 |
hwd_context_t * ctx )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
int i, index;
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
( void ) ptr;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
for ( i = 0; i < count; i++ ) {
|
|
Packit |
577717 |
index = native[i].ni_event;
|
|
Packit |
577717 |
native[i].ni_position = _coretemp_native_events[index].resources.selector - 1;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* This function has to set the bits needed to count different domains
|
|
Packit |
577717 |
* In particular: PAPI_DOM_USER, PAPI_DOM_KERNEL PAPI_DOM_OTHER
|
|
Packit |
577717 |
* By default return PAPI_EINVAL if none of those are specified
|
|
Packit |
577717 |
* and PAPI_OK with success
|
|
Packit |
577717 |
* PAPI_DOM_USER is only user context is counted
|
|
Packit |
577717 |
* PAPI_DOM_KERNEL is only the Kernel/OS context is counted
|
|
Packit |
577717 |
* PAPI_DOM_OTHER is Exception/transient mode (like user TLB misses)
|
|
Packit |
577717 |
* PAPI_DOM_ALL is all of the domains
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_set_domain( hwd_control_state_t * cntl, int domain )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
(void) cntl;
|
|
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
|
|
Packit |
577717 |
_coretemp_reset( hwd_context_t *ctx, hwd_control_state_t *ctl )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
( void ) ctx;
|
|
Packit |
577717 |
( void ) ctl;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
* Native Event functions
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_ntv_enum_events( unsigned int *EventCode, int modifier )
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int index;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
switch ( modifier ) {
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PAPI_ENUM_FIRST:
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if (num_events==0) {
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
*EventCode = 0;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
case PAPI_ENUM_EVENTS:
|
|
Packit |
577717 |
|
|
Packit |
577717 |
index = *EventCode;
|
|
Packit |
577717 |
|
|
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 |
break;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
default:
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_EINVAL;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_ntv_code_to_name( 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 |
strncpy( name, _coretemp_native_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
|
|
Packit |
577717 |
_coretemp_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 |
strncpy( name, _coretemp_native_events[index].description, len );
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
return PAPI_ENOEVNT;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
static int
|
|
Packit |
577717 |
_coretemp_ntv_code_to_info(unsigned int EventCode, PAPI_event_info_t *info)
|
|
Packit |
577717 |
{
|
|
Packit |
577717 |
|
|
Packit |
577717 |
int index = EventCode;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
if ( ( index < 0) || (index >= num_events )) return PAPI_ENOEVNT;
|
|
Packit |
577717 |
|
|
Packit |
577717 |
strncpy( info->symbol, _coretemp_native_events[index].name, sizeof(info->symbol));
|
|
Packit |
577717 |
strncpy( info->long_descr, _coretemp_native_events[index].description, sizeof(info->long_descr));
|
|
Packit |
577717 |
strncpy( info->units, _coretemp_native_events[index].units, sizeof(info->units));
|
|
Packit |
577717 |
info->units[sizeof(info->units)-1] = '\0';
|
|
Packit |
577717 |
|
|
Packit |
577717 |
return PAPI_OK;
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/*
|
|
Packit |
577717 |
*
|
|
Packit |
577717 |
*/
|
|
Packit |
577717 |
papi_vector_t _coretemp_vector = {
|
|
Packit |
577717 |
.cmp_info = {
|
|
Packit |
577717 |
/* default component information (unspecified values are initialized to 0) */
|
|
Packit |
577717 |
.name = "coretemp",
|
|
Packit |
577717 |
.short_name = "coretemp",
|
|
Packit |
577717 |
.description = "Linux hwmon temperature and other info",
|
|
Packit |
577717 |
.version = "4.2.1",
|
|
Packit |
577717 |
.num_mpx_cntrs = CORETEMP_MAX_COUNTERS,
|
|
Packit |
577717 |
.num_cntrs = CORETEMP_MAX_COUNTERS,
|
|
Packit |
577717 |
.default_domain = PAPI_DOM_ALL,
|
|
Packit |
577717 |
.available_domains = 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 |
|
|
Packit |
577717 |
/* component specific cmp_info initializations */
|
|
Packit |
577717 |
.fast_real_timer = 0,
|
|
Packit |
577717 |
.fast_virtual_timer = 0,
|
|
Packit |
577717 |
.attach = 0,
|
|
Packit |
577717 |
.attach_must_ptrace = 0,
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
/* sizes of framework-opaque component-private structures */
|
|
Packit |
577717 |
.size = {
|
|
Packit |
577717 |
.context = sizeof ( CORETEMP_context_t ),
|
|
Packit |
577717 |
.control_state = sizeof ( CORETEMP_control_state_t ),
|
|
Packit |
577717 |
.reg_value = sizeof ( CORETEMP_register_t ),
|
|
Packit |
577717 |
.reg_alloc = sizeof ( CORETEMP_reg_alloc_t ),
|
|
Packit |
577717 |
}
|
|
Packit |
577717 |
,
|
|
Packit |
577717 |
/* function pointers in this component */
|
|
Packit |
577717 |
.init_thread = _coretemp_init_thread,
|
|
Packit |
577717 |
.init_component = _coretemp_init_component,
|
|
Packit |
577717 |
.init_control_state = _coretemp_init_control_state,
|
|
Packit |
577717 |
.start = _coretemp_start,
|
|
Packit |
577717 |
.stop = _coretemp_stop,
|
|
Packit |
577717 |
.read = _coretemp_read,
|
|
Packit |
577717 |
.shutdown_thread = _coretemp_shutdown_thread,
|
|
Packit |
577717 |
.shutdown_component = _coretemp_shutdown_component,
|
|
Packit |
577717 |
.ctl = _coretemp_ctl,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.update_control_state = _coretemp_update_control_state,
|
|
Packit |
577717 |
.set_domain = _coretemp_set_domain,
|
|
Packit |
577717 |
.reset = _coretemp_reset,
|
|
Packit |
577717 |
|
|
Packit |
577717 |
.ntv_enum_events = _coretemp_ntv_enum_events,
|
|
Packit |
577717 |
.ntv_code_to_name = _coretemp_ntv_code_to_name,
|
|
Packit |
577717 |
.ntv_code_to_descr = _coretemp_ntv_code_to_descr,
|
|
Packit |
577717 |
.ntv_code_to_info = _coretemp_ntv_code_to_info,
|
|
Packit |
577717 |
};
|