From c9583c692da90f58f0d885864d7374e21ef385b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Sun, 13 Dec 2020 16:46:10 +0100 Subject: [PATCH] Handle absence of package CPU temperature Resolves: #389 --- linux/LibSensors.c | 67 +++++++++++++++++++++++++++++++++++----- linux/LibSensors.h | 2 +- linux/LinuxProcessList.c | 37 +--------------------- 3 files changed, 61 insertions(+), 45 deletions(-) diff --git a/linux/LibSensors.c b/linux/LibSensors.c index d006874f..cb3f1446 100644 --- a/linux/LibSensors.c +++ b/linux/LibSensors.c @@ -4,6 +4,7 @@ #include #include +#include #include #include "XUtils.h" @@ -16,6 +17,7 @@ static int (*sym_sensors_snprintf_chip_name)(char*, size_t, const sensors_chip_n 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 char* (*sym_sensors_get_label)(const sensors_chip_name*, const sensors_feature*); static void* dlopenHandle = NULL; @@ -45,6 +47,7 @@ int LibSensors_init(FILE* input) { resolve(sensors_get_features); resolve(sensors_get_subfeature); resolve(sensors_get_value); + resolve(sensors_get_label); #undef resolve } @@ -68,11 +71,14 @@ void LibSensors_cleanup(void) { } } -int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) { - if (!dlopenHandle) - return -ENOTSUP; +void LibSensors_getCPUTemperatures(CPUData* cpus, unsigned int cpuCount) { + for (unsigned int i = 0; i <= cpuCount; i++) + cpus[i].temperature = NAN; - int tempCount = 0; + if (!dlopenHandle) + return; + + unsigned int coreTempCount = 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)) { @@ -86,7 +92,22 @@ int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) { if (feature->type != SENSORS_FEATURE_TEMP) continue; - if (feature->number > cpuCount) + char* label = sym_sensors_get_label(chip, feature); + if (!label) + continue; + + unsigned int tempId; + if (String_startsWith(label, "Package ")) { + tempId = 0; + } else if (String_startsWith(label, "Core ")) { + tempId = 1 + atoi(label + strlen("Core ")); + } else { + tempId = UINT_MAX; + } + + free(label); + + if (tempId > cpuCount) continue; const sensors_subfeature *sub_feature = sym_sensors_get_subfeature(chip, feature, SENSORS_SUBFEATURE_TEMP_INPUT); @@ -96,13 +117,43 @@ int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount) { if (r != 0) continue; - cpus[feature->number].temperature = temp; - tempCount++; + cpus[tempId].temperature = temp; + if (tempId > 0) + coreTempCount++; } } } - return tempCount; + const double packageTemp = cpus[0].temperature; + + /* Only package temperature - copy to all cpus */ + if (coreTempCount == 0 && !isnan(packageTemp)) { + for (unsigned int i = 1; i <= cpuCount; i++) + cpus[i].temperature = packageTemp; + + return; + } + + /* No package temperature - set to max core temperature */ + if (isnan(packageTemp) && coreTempCount != 0) { + double maxTemp = NAN; + for (unsigned int i = 1; i <= cpuCount; i++) { + const double coreTemp = cpus[i].temperature; + if (isnan(coreTemp)) + continue; + + maxTemp = MAXIMUM(maxTemp, coreTemp); + } + + cpus[0].temperature = maxTemp; + } + + /* Half the temperatures, probably HT/SMT - copy to second half */ + const unsigned int delta = cpuCount / 2; + if (coreTempCount == delta) { + for (unsigned int i = 1; i <= delta; i++) + cpus[i + delta].temperature = cpus[i].temperature; + } } #endif /* HAVE_SENSORS_SENSORS_H */ diff --git a/linux/LibSensors.h b/linux/LibSensors.h index ed9be7b0..cceeedbf 100644 --- a/linux/LibSensors.h +++ b/linux/LibSensors.h @@ -11,6 +11,6 @@ int LibSensors_init(FILE* input); void LibSensors_cleanup(void); -int LibSensors_getCPUTemperatures(CPUData* cpus, int cpuCount); +void LibSensors_getCPUTemperatures(CPUData* cpus, unsigned int cpuCount); #endif /* HEADER_LibSensors */ diff --git a/linux/LinuxProcessList.c b/linux/LinuxProcessList.c index 45161290..b58afa35 100644 --- a/linux/LinuxProcessList.c +++ b/linux/LinuxProcessList.c @@ -1832,41 +1832,6 @@ static void LinuxProcessList_scanCPUFrequency(LinuxProcessList* this) { scanCPUFreqencyFromCPUinfo(this); } -#ifdef HAVE_SENSORS_SENSORS_H -static void LinuxProcessList_scanCPUTemperature(LinuxProcessList* this) { - const int cpuCount = this->super.cpuCount; - - for (int i = 0; i <= cpuCount; i++) { - this->cpus[i].temperature = NAN; - } - - int r = LibSensors_getCPUTemperatures(this->cpus, cpuCount); - - /* No temperature - nothing to do */ - if (r <= 0) - return; - - /* Only package temperature - copy to all cpus */ - if (r == 1 && !isnan(this->cpus[0].temperature)) { - double packageTemp = this->cpus[0].temperature; - for (int i = 1; i <= cpuCount; i++) { - this->cpus[i].temperature = packageTemp; - } - - return; - } - - /* Half the temperatures, probably HT/SMT - copy to second half */ - if (r >= 2 && (r - 1) == (cpuCount / 2)) { - for (int i = cpuCount / 2 + 1; i <= cpuCount; i++) { - this->cpus[i].temperature = this->cpus[i/2].temperature; - } - - return; - } -} -#endif - void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { LinuxProcessList* this = (LinuxProcessList*) super; const Settings* settings = super->settings; @@ -1884,7 +1849,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) { #ifdef HAVE_SENSORS_SENSORS_H if (settings->showCPUTemperature) - LinuxProcessList_scanCPUTemperature(this); + LibSensors_getCPUTemperatures(this->cpus, this->super.cpuCount); #endif // in pause mode only gather global data for meters (CPU/memory/...)