mirror of https://github.com/xzeldon/htop.git
Dynamically load libsensors at runtime
This commit is contained in:
parent
f7a8952933
commit
b76eaf187a
|
@ -79,7 +79,7 @@ static void CPUMeter_updateValues(Meter* this, char* buffer, int size) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
if (this->pl->settings->showCPUTemperature) {
|
if (this->pl->settings->showCPUTemperature) {
|
||||||
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
|
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
|
||||||
if (isnan(cpuTemperature))
|
if (isnan(cpuTemperature))
|
||||||
|
@ -150,7 +150,7 @@ static void CPUMeter_display(const Object* cast, RichString* out) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
if (this->pl->settings->showCPUTemperature) {
|
if (this->pl->settings->showCPUTemperature) {
|
||||||
char cpuTemperatureBuffer[10];
|
char cpuTemperatureBuffer[10];
|
||||||
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
|
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
|
||||||
|
|
|
@ -116,8 +116,8 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
|
||||||
Panel_add(super, (Object*) CheckItem_newByRef("Add guest time in CPU meter percentage", &(settings->accountGuestInCPUMeter)));
|
Panel_add(super, (Object*) CheckItem_newByRef("Add guest time in CPU meter percentage", &(settings->accountGuestInCPUMeter)));
|
||||||
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU percentage numerically", &(settings->showCPUUsage)));
|
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU percentage numerically", &(settings->showCPUUsage)));
|
||||||
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU frequency", &(settings->showCPUFrequency)));
|
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU frequency", &(settings->showCPUFrequency)));
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU temperature", &(settings->showCPUTemperature)));
|
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU temperature (requires libsensors)", &(settings->showCPUTemperature)));
|
||||||
Panel_add(super, (Object*) CheckItem_newByRef("- Show temperature in degree Fahrenheit instead of Celsius", &(settings->degreeFahrenheit)));
|
Panel_add(super, (Object*) CheckItem_newByRef("- Show temperature in degree Fahrenheit instead of Celsius", &(settings->degreeFahrenheit)));
|
||||||
#endif
|
#endif
|
||||||
Panel_add(super, (Object*) CheckItem_newByRef("Enable the mouse", &(settings->enableMouse)));
|
Panel_add(super, (Object*) CheckItem_newByRef("Enable the mouse", &(settings->enableMouse)));
|
||||||
|
|
|
@ -126,6 +126,7 @@ myhtopheaders = \
|
||||||
linux_platform_headers = \
|
linux_platform_headers = \
|
||||||
linux/IOPriority.h \
|
linux/IOPriority.h \
|
||||||
linux/IOPriorityPanel.h \
|
linux/IOPriorityPanel.h \
|
||||||
|
linux/LibSensors.h \
|
||||||
linux/LinuxProcess.h \
|
linux/LinuxProcess.h \
|
||||||
linux/LinuxProcessList.h \
|
linux/LinuxProcessList.h \
|
||||||
linux/Platform.h \
|
linux/Platform.h \
|
||||||
|
@ -142,6 +143,7 @@ if HTOP_LINUX
|
||||||
AM_LDFLAGS += -rdynamic
|
AM_LDFLAGS += -rdynamic
|
||||||
myhtopplatsources = \
|
myhtopplatsources = \
|
||||||
linux/IOPriorityPanel.c \
|
linux/IOPriorityPanel.c \
|
||||||
|
linux/LibSensors.c \
|
||||||
linux/LinuxProcess.c \
|
linux/LinuxProcess.c \
|
||||||
linux/LinuxProcessList.c \
|
linux/LinuxProcessList.c \
|
||||||
linux/Platform.c \
|
linux/Platform.c \
|
||||||
|
|
|
@ -183,7 +183,7 @@ static bool Settings_read(Settings* this, const char* fileName, int initialCpuCo
|
||||||
this->showCPUUsage = atoi(option[1]);
|
this->showCPUUsage = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "show_cpu_frequency")) {
|
} else if (String_eq(option[0], "show_cpu_frequency")) {
|
||||||
this->showCPUFrequency = atoi(option[1]);
|
this->showCPUFrequency = atoi(option[1]);
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
} else if (String_eq(option[0], "show_cpu_temperature")) {
|
} else if (String_eq(option[0], "show_cpu_temperature")) {
|
||||||
this->showCPUTemperature = atoi(option[1]);
|
this->showCPUTemperature = atoi(option[1]);
|
||||||
} else if (String_eq(option[0], "degree_fahrenheit")) {
|
} else if (String_eq(option[0], "degree_fahrenheit")) {
|
||||||
|
@ -292,7 +292,7 @@ bool Settings_write(Settings* this) {
|
||||||
fprintf(fd, "cpu_count_from_one=%d\n", (int) this->countCPUsFromOne);
|
fprintf(fd, "cpu_count_from_one=%d\n", (int) this->countCPUsFromOne);
|
||||||
fprintf(fd, "show_cpu_usage=%d\n", (int) this->showCPUUsage);
|
fprintf(fd, "show_cpu_usage=%d\n", (int) this->showCPUUsage);
|
||||||
fprintf(fd, "show_cpu_frequency=%d\n", (int) this->showCPUFrequency);
|
fprintf(fd, "show_cpu_frequency=%d\n", (int) this->showCPUFrequency);
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
fprintf(fd, "show_cpu_temperature=%d\n", (int) this->showCPUTemperature);
|
fprintf(fd, "show_cpu_temperature=%d\n", (int) this->showCPUTemperature);
|
||||||
fprintf(fd, "degree_fahrenheit=%d\n", (int) this->degreeFahrenheit);
|
fprintf(fd, "degree_fahrenheit=%d\n", (int) this->degreeFahrenheit);
|
||||||
#endif
|
#endif
|
||||||
|
@ -328,7 +328,7 @@ Settings* Settings_new(int initialCpuCount) {
|
||||||
this->countCPUsFromOne = false;
|
this->countCPUsFromOne = false;
|
||||||
this->showCPUUsage = true;
|
this->showCPUUsage = true;
|
||||||
this->showCPUFrequency = false;
|
this->showCPUFrequency = false;
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
this->showCPUTemperature = false;
|
this->showCPUTemperature = false;
|
||||||
this->degreeFahrenheit = false;
|
this->degreeFahrenheit = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,7 +38,7 @@ typedef struct Settings_ {
|
||||||
bool detailedCPUTime;
|
bool detailedCPUTime;
|
||||||
bool showCPUUsage;
|
bool showCPUUsage;
|
||||||
bool showCPUFrequency;
|
bool showCPUFrequency;
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
bool showCPUTemperature;
|
bool showCPUTemperature;
|
||||||
bool degreeFahrenheit;
|
bool degreeFahrenheit;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -307,13 +307,11 @@ then
|
||||||
])
|
])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
AC_ARG_ENABLE(sensors, [AS_HELP_STRING([--enable-sensors], [enable libsensors support for reading temperature data.])],, enable_sensors="check")
|
AC_ARG_ENABLE(sensors, [AS_HELP_STRING([--with-sensors], [Compile with libsensors support for reading temperature data. Only requires libsensors headers at compile time, at runtime libsensors is loaded via dlopen.])],, enable_sensors="check")
|
||||||
if test "x$enable_sensors" = xyes; then
|
if test "x$enable_sensors" = xyes; then
|
||||||
AC_CHECK_LIB([sensors], [sensors_get_value], [], [missing_libraries="$missing_libraries libsensors"])
|
|
||||||
AC_CHECK_HEADERS([sensors/sensors.h], [], [missing_headers="$missing_headers $ac_header"])
|
AC_CHECK_HEADERS([sensors/sensors.h], [], [missing_headers="$missing_headers $ac_header"])
|
||||||
elif test "x$enable_sensors" = xcheck; then
|
elif test "x$enable_sensors" = xcheck; then
|
||||||
enable_sensors=yes
|
enable_sensors=yes
|
||||||
AC_CHECK_LIB([sensors], [sensors_get_value], [], [enable_sensors=no])
|
|
||||||
AC_CHECK_HEADERS([sensors/sensors.h], [], [enable_sensors=no])
|
AC_CHECK_HEADERS([sensors/sensors.h], [], [enable_sensors=no])
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
#include "LibSensors.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
|
|
||||||
|
#include <dlfcn.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <sensors/sensors.h>
|
||||||
|
|
||||||
|
#include "XUtils.h"
|
||||||
|
|
||||||
|
|
||||||
|
static int (*sym_sensors_init)(FILE*);
|
||||||
|
static void (*sym_sensors_cleanup)(void);
|
||||||
|
static const sensors_chip_name* (*sym_sensors_get_detected_chips)(const sensors_chip_name*, int*);
|
||||||
|
static int (*sym_sensors_snprintf_chip_name)(char*, size_t, const sensors_chip_name*);
|
||||||
|
static const sensors_feature* (*sym_sensors_get_features)(const sensors_chip_name*, int*);
|
||||||
|
static const sensors_subfeature* (*sym_sensors_get_subfeature)(const sensors_chip_name*, const sensors_feature*, sensors_subfeature_type);
|
||||||
|
static int (*sym_sensors_get_value)(const sensors_chip_name*, int, double*);
|
||||||
|
|
||||||
|
static void* dlopenHandle = NULL;
|
||||||
|
|
||||||
|
int LibSensors_init(FILE* input) {
|
||||||
|
if (!dlopenHandle) {
|
||||||
|
dlopenHandle = dlopen("libsensors.so", RTLD_LAZY);
|
||||||
|
if (!dlopenHandle)
|
||||||
|
goto dlfailure;
|
||||||
|
|
||||||
|
/* Clear any errors */
|
||||||
|
dlerror();
|
||||||
|
|
||||||
|
#define resolve(symbolname) do { \
|
||||||
|
*(void **)(&sym_##symbolname) = dlsym(dlopenHandle, #symbolname); \
|
||||||
|
if (!sym_##symbolname || dlerror() != NULL) \
|
||||||
|
goto dlfailure; \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
resolve(sensors_init);
|
||||||
|
resolve(sensors_cleanup);
|
||||||
|
resolve(sensors_get_detected_chips);
|
||||||
|
resolve(sensors_snprintf_chip_name);
|
||||||
|
resolve(sensors_get_features);
|
||||||
|
resolve(sensors_get_subfeature);
|
||||||
|
resolve(sensors_get_value);
|
||||||
|
|
||||||
|
#undef resolve
|
||||||
|
}
|
||||||
|
|
||||||
|
return sym_sensors_init(input);
|
||||||
|
|
||||||
|
dlfailure:
|
||||||
|
if (dlopenHandle) {
|
||||||
|
dlclose(dlopenHandle);
|
||||||
|
dlopenHandle = NULL;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void LibSensors_cleanup(void) {
|
||||||
|
if (dlopenHandle) {
|
||||||
|
sym_sensors_cleanup();
|
||||||
|
|
||||||
|
dlclose(dlopenHandle);
|
||||||
|
dlopenHandle = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) {
|
||||||
|
if (!dlopenHandle)
|
||||||
|
return -ENOTSUP;
|
||||||
|
|
||||||
|
int tempCount = 0;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
for (const sensors_chip_name *chip = sym_sensors_get_detected_chips(NULL, &n); chip; chip = sym_sensors_get_detected_chips(NULL, &n)) {
|
||||||
|
char buffer[32];
|
||||||
|
sym_sensors_snprintf_chip_name(buffer, sizeof(buffer), chip);
|
||||||
|
if (!String_startsWith(buffer, "coretemp") && !String_startsWith(buffer, "cpu_thermal"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int m = 0;
|
||||||
|
for (const sensors_feature *feature = sym_sensors_get_features(chip, &m); feature; feature = sym_sensors_get_features(chip, &m)) {
|
||||||
|
if (feature->type != SENSORS_FEATURE_TEMP)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (feature->number > cpuCount)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const sensors_subfeature *sub_feature = sym_sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
|
||||||
|
if (sub_feature) {
|
||||||
|
double temp;
|
||||||
|
int r = sym_sensors_get_value(chip, sub_feature->number, &temp);
|
||||||
|
if (r != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
cpus[feature->number].temperature = temp;
|
||||||
|
tempCount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tempCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* HAVE_SENSORS_SENSORS_H */
|
|
@ -0,0 +1,16 @@
|
||||||
|
#ifndef HEADER_LibSensors
|
||||||
|
#define HEADER_LibSensors
|
||||||
|
|
||||||
|
#include "config.h" // IWYU pragma: keep
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "LinuxProcessList.h"
|
||||||
|
|
||||||
|
|
||||||
|
int LibSensors_init(FILE* input);
|
||||||
|
void LibSensors_cleanup(void);
|
||||||
|
|
||||||
|
int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount);
|
||||||
|
|
||||||
|
#endif /* HEADER_LibSensors */
|
|
@ -53,8 +53,8 @@ in the source distribution for its full text.
|
||||||
#include <sys/sysmacros.h>
|
#include <sys/sysmacros.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
#include <sensors/sensors.h>
|
#include "LibSensors.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -1794,41 +1794,7 @@ static void LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) {
|
||||||
scanCPUFreqencyFromCPUinfo(this);
|
scanCPUFreqencyFromCPUinfo(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
static int getCPUTemperatures(CPUData* cpus, int cpuCount) {
|
|
||||||
int tempCount = 0;
|
|
||||||
|
|
||||||
int n = 0;
|
|
||||||
for (const sensors_chip_name *chip = sensors_get_detected_chips(NULL, &n); chip; chip = sensors_get_detected_chips(NULL, &n)) {
|
|
||||||
char buffer[32];
|
|
||||||
sensors_snprintf_chip_name(buffer, sizeof(buffer), chip);
|
|
||||||
if (!String_startsWith(buffer, "coretemp") && !String_startsWith(buffer, "cpu_thermal"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int m = 0;
|
|
||||||
for (const sensors_feature *feature = sensors_get_features(chip, &m); feature; feature = sensors_get_features(chip, &m)) {
|
|
||||||
if (feature->type != SENSORS_FEATURE_TEMP)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (feature->number > cpuCount)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
const sensors_subfeature *sub_feature = sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT);
|
|
||||||
if (sub_feature) {
|
|
||||||
double temp;
|
|
||||||
int r = sensors_get_value(chip, sub_feature->number, &temp);
|
|
||||||
if (r != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
cpus[feature->number].temperature = temp;
|
|
||||||
tempCount++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tempCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void LinuxProcessList_scanCPUTemperature(LinuxProcessList* this) {
|
static void LinuxProcessList_scanCPUTemperature(LinuxProcessList* this) {
|
||||||
const int cpuCount = this->super.cpuCount;
|
const int cpuCount = this->super.cpuCount;
|
||||||
|
|
||||||
|
@ -1836,10 +1802,10 @@ static void LinuxProcessList_scanCPUTemperature(LinuxProcessList* this) {
|
||||||
this->cpus[i].temperature = NAN;
|
this->cpus[i].temperature = NAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
int r = getCPUTemperatures(this->cpus, cpuCount);
|
int r = LibSensors_getCPUTemperatures(this->cpus, cpuCount);
|
||||||
|
|
||||||
/* No temperature - nothing to do */
|
/* No temperature - nothing to do */
|
||||||
if (r == 0)
|
if (r <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Only package temperature - copy to all cpus */
|
/* Only package temperature - copy to all cpus */
|
||||||
|
@ -1878,7 +1844,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
|
||||||
LinuxProcessList_scanCPUFrequency(this);
|
LinuxProcessList_scanCPUFrequency(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
if (settings->showCPUTemperature)
|
if (settings->showCPUTemperature)
|
||||||
LinuxProcessList_scanCPUTemperature(this);
|
LinuxProcessList_scanCPUTemperature(this);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,7 +48,7 @@ typedef struct CPUData_ {
|
||||||
|
|
||||||
double frequency;
|
double frequency;
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
double temperature;
|
double temperature;
|
||||||
#endif
|
#endif
|
||||||
} CPUData;
|
} CPUData;
|
||||||
|
|
|
@ -61,10 +61,11 @@ in the source distribution for its full text.
|
||||||
#include "zfs/ZfsArcStats.h"
|
#include "zfs/ZfsArcStats.h"
|
||||||
#include "zfs/ZfsCompressedArcMeter.h"
|
#include "zfs/ZfsCompressedArcMeter.h"
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
#include <sensors/sensors.h>
|
#include "LibSensors.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, (int)M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
ProcessField Platform_defaultFields[] = { PID, USER, PRIORITY, NICE, M_VIRT, M_RESIDENT, (int)M_SHARE, STATE, PERCENT_CPU, PERCENT_MEM, TIME, COMM, 0 };
|
||||||
|
|
||||||
int Platform_numberOfFields = LAST_PROCESSFIELD;
|
int Platform_numberOfFields = LAST_PROCESSFIELD;
|
||||||
|
@ -119,14 +120,14 @@ void Platform_init(void) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
sensors_init(NULL);
|
LibSensors_init(NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Platform_done(void) {
|
void Platform_done(void) {
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
sensors_cleanup();
|
LibSensors_cleanup();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +272,7 @@ double Platform_setCPUValues(Meter* this, int cpu) {
|
||||||
|
|
||||||
v[CPU_METER_FREQUENCY] = cpuData->frequency;
|
v[CPU_METER_FREQUENCY] = cpuData->frequency;
|
||||||
|
|
||||||
#ifdef HAVE_LIBSENSORS
|
#ifdef HAVE_SENSORS_SENSORS_H
|
||||||
v[CPU_METER_TEMPERATURE] = cpuData->temperature;
|
v[CPU_METER_TEMPERATURE] = cpuData->temperature;
|
||||||
#else
|
#else
|
||||||
v[CPU_METER_TEMPERATURE] = NAN;
|
v[CPU_METER_TEMPERATURE] = NAN;
|
||||||
|
|
Loading…
Reference in New Issue