summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Göttsche <cgzones@googlemail.com>2020-12-22 20:02:01 +0100
committerChristian Goettsche <cgzones@googlemail.com>2021-02-05 16:32:25 +0100
commitfd2a0cf4219ac6b000e3ef46e1958edd2ff41a67 (patch)
tree1c556519ebb1c235f2e8954e2de25d35dd1c2582
parent64a1ab848f4cba7b9dd4705a169034e39048d27d (diff)
FreeBSD: add support for CPU frequency and temperature
-rw-r--r--CPUMeter.c4
-rw-r--r--DisplayOptionsPanel.c12
-rw-r--r--Settings.c6
-rw-r--r--Settings.h2
-rw-r--r--configure.ac3
-rw-r--r--freebsd/FreeBSDProcessList.c66
-rw-r--r--freebsd/FreeBSDProcessList.h3
-rw-r--r--freebsd/Platform.c4
8 files changed, 88 insertions, 12 deletions
diff --git a/CPUMeter.c b/CPUMeter.c
index a39a3cb9..707eec16 100644
--- a/CPUMeter.c
+++ b/CPUMeter.c
@@ -79,7 +79,7 @@ static void CPUMeter_updateValues(Meter* this, char* buffer, size_t size) {
}
}
- #ifdef HAVE_SENSORS_SENSORS_H
+ #ifdef BUILD_WITH_CPU_TEMP
if (this->pl->settings->showCPUTemperature) {
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
if (isnan(cpuTemperature))
@@ -150,7 +150,7 @@ static void CPUMeter_display(const Object* cast, RichString* out) {
}
}
- #ifdef HAVE_SENSORS_SENSORS_H
+ #ifdef BUILD_WITH_CPU_TEMP
if (this->pl->settings->showCPUTemperature) {
char cpuTemperatureBuffer[10];
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
diff --git a/DisplayOptionsPanel.c b/DisplayOptionsPanel.c
index 7e02b231..8f938fd6 100644
--- a/DisplayOptionsPanel.c
+++ b/DisplayOptionsPanel.c
@@ -116,8 +116,16 @@ 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("Also show CPU percentage numerically", &(settings->showCPUUsage)));
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU frequency", &(settings->showCPUFrequency)));
- #ifdef HAVE_SENSORS_SENSORS_H
- Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU temperature (requires libsensors)", &(settings->showCPUTemperature)));
+ #ifdef BUILD_WITH_CPU_TEMP
+ Panel_add(super, (Object*) CheckItem_newByRef(
+ #ifdef HTOP_LINUX
+ "Also show CPU temperature (requires libsensors)",
+ #elif defined(HTOP_FREEBSD)
+ "Also show CPU temperature",
+ #else
+ #error Unknown temperature implementation!
+ #endif
+ &(settings->showCPUTemperature)));
Panel_add(super, (Object*) CheckItem_newByRef("- Show temperature in degree Fahrenheit instead of Celsius", &(settings->degreeFahrenheit)));
#endif
Panel_add(super, (Object*) CheckItem_newByRef("Enable the mouse", &(settings->enableMouse)));
diff --git a/Settings.c b/Settings.c
index f12a51f4..421ec552 100644
--- a/Settings.c
+++ b/Settings.c
@@ -205,7 +205,7 @@ static bool Settings_read(Settings* this, const char* fileName, int initialCpuCo
this->showCPUUsage = atoi(option[1]);
} else if (String_eq(option[0], "show_cpu_frequency")) {
this->showCPUFrequency = atoi(option[1]);
- #ifdef HAVE_SENSORS_SENSORS_H
+ #ifdef BUILD_WITH_CPU_TEMP
} else if (String_eq(option[0], "show_cpu_temperature")) {
this->showCPUTemperature = atoi(option[1]);
} else if (String_eq(option[0], "degree_fahrenheit")) {
@@ -319,7 +319,7 @@ bool Settings_write(Settings* this) {
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_frequency=%d\n", (int) this->showCPUFrequency);
- #ifdef HAVE_SENSORS_SENSORS_H
+ #ifdef BUILD_WITH_CPU_TEMP
fprintf(fd, "show_cpu_temperature=%d\n", (int) this->showCPUTemperature);
fprintf(fd, "degree_fahrenheit=%d\n", (int) this->degreeFahrenheit);
#endif
@@ -358,7 +358,7 @@ Settings* Settings_new(int initialCpuCount) {
this->countCPUsFromOne = false;
this->showCPUUsage = true;
this->showCPUFrequency = false;
- #ifdef HAVE_SENSORS_SENSORS_H
+ #ifdef BUILD_WITH_CPU_TEMP
this->showCPUTemperature = false;
this->degreeFahrenheit = false;
#endif
diff --git a/Settings.h b/Settings.h
index fdaf3e37..00bcfd50 100644
--- a/Settings.h
+++ b/Settings.h
@@ -41,7 +41,7 @@ typedef struct Settings_ {
bool detailedCPUTime;
bool showCPUUsage;
bool showCPUFrequency;
- #ifdef HAVE_SENSORS_SENSORS_H
+ #ifdef BUILD_WITH_CPU_TEMP
bool showCPUTemperature;
bool degreeFahrenheit;
#endif
diff --git a/configure.ac b/configure.ac
index 7bac0426..01a9b266 100644
--- a/configure.ac
+++ b/configure.ac
@@ -505,6 +505,9 @@ case "$enable_sensors" in
AC_MSG_ERROR([bad value '$enable_sensors' for --enable-sensors])
;;
esac
+if test "$enable_sensors" = yes || test "$my_htop_platform" = freebsd; then
+ AC_DEFINE([BUILD_WITH_CPU_TEMP], [1], [Define if CPU temperature option should be enabled.])
+fi
# ----------------------------------------------------------------------
diff --git a/freebsd/FreeBSDProcessList.c b/freebsd/FreeBSDProcessList.c
index 91e1d4ca..cee8ec52 100644
--- a/freebsd/FreeBSDProcessList.c
+++ b/freebsd/FreeBSDProcessList.c
@@ -12,6 +12,7 @@ in the source distribution for its full text.
#include <assert.h>
#include <dirent.h>
#include <limits.h>
+#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <sys/_iovec.h>
@@ -171,7 +172,7 @@ void ProcessList_delete(ProcessList* this) {
free(this);
}
-static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
+static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) {
const FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl;
int cpus = pl->cpuCount; // actual CPU count
@@ -250,6 +251,67 @@ static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
cpuData->systemAllPercent = cp_time_p[CP_SYS] + cp_time_p[CP_INTR];
// this one is not really used
//cpuData->idlePercent = cp_time_p[CP_IDLE];
+
+ cpuData->temperature = NAN;
+ cpuData->frequency = NAN;
+
+ const int coreId = (cpus == 1) ? 0 : (i - 1);
+ if (coreId < 0)
+ continue;
+
+ // TODO: test with hyperthreading and multi-cpu systems
+ if (pl->settings->showCPUTemperature) {
+ int temperature;
+ size_t len = sizeof(temperature);
+ char mibBuffer[32];
+ xSnprintf(mibBuffer, sizeof(mibBuffer), "dev.cpu.%d.temperature", coreId);
+ int r = sysctlbyname(mibBuffer, &temperature, &len, NULL, 0);
+ if (r == 0)
+ cpuData->temperature = (double)(temperature - 2732) / 10.0; // convert from deci-Kelvin to Celsius
+ }
+
+ // TODO: test with hyperthreading and multi-cpu systems
+ if (pl->settings->showCPUFrequency) {
+ int frequency;
+ size_t len = sizeof(frequency);
+ char mibBuffer[32];
+ xSnprintf(mibBuffer, sizeof(mibBuffer), "dev.cpu.%d.freq", coreId);
+ int r = sysctlbyname(mibBuffer, &frequency, &len, NULL, 0);
+ if (r == 0)
+ cpuData->frequency = frequency; // keep in MHz
+ }
+ }
+
+ // calculate max temperature and avg frequency for average meter and
+ // propagate frequency to all cores if only supplied for CPU 0
+ if (cpus > 1) {
+ if (pl->settings->showCPUTemperature) {
+ double maxTemp = NAN;
+ for (int i = 1; i < maxcpu; i++) {
+ const double coreTemp = fpl->cpus[i].temperature;
+ if (isnan(coreTemp))
+ continue;
+
+ maxTemp = MAXIMUM(maxTemp, coreTemp);
+ }
+
+ fpl->cpus[0].temperature = maxTemp;
+ }
+
+ if (pl->settings->showCPUFrequency) {
+ const double coreZeroFreq = fpl->cpus[1].frequency;
+ double freqSum = coreZeroFreq;
+ if (!isnan(coreZeroFreq)) {
+ for (int i = 2; i < maxcpu; i++) {
+ if (isnan(fpl->cpus[i].frequency))
+ fpl->cpus[i].frequency = coreZeroFreq;
+
+ freqSum += fpl->cpus[i].frequency;
+ }
+
+ fpl->cpus[0].frequency = freqSum / (maxcpu - 1);
+ }
+ }
}
}
@@ -443,7 +505,7 @@ void ProcessList_goThroughEntries(ProcessList* super, bool pauseProcessUpdate) {
openzfs_sysctl_updateArcStats(&fpl->zfs);
FreeBSDProcessList_scanMemoryInfo(super);
- FreeBSDProcessList_scanCPUTime(super);
+ FreeBSDProcessList_scanCPU(super);
// in pause mode only gather global data for meters (CPU/memory/...)
if (pauseProcessUpdate) {
diff --git a/freebsd/FreeBSDProcessList.h b/freebsd/FreeBSDProcessList.h
index 44d26912..398bb827 100644
--- a/freebsd/FreeBSDProcessList.h
+++ b/freebsd/FreeBSDProcessList.h
@@ -23,6 +23,9 @@ typedef struct CPUData_ {
double systemPercent;
double irqPercent;
double systemAllPercent;
+
+ double frequency;
+ double temperature;
} CPUData;
typedef struct FreeBSDProcessList_ {
diff --git a/freebsd/Platform.c b/freebsd/Platform.c
index 9f8c051f..1f6189ef 100644
--- a/freebsd/Platform.c
+++ b/freebsd/Platform.c
@@ -209,8 +209,8 @@ double Platform_setCPUValues(Meter* this, int cpu) {
percent = CLAMP(percent, 0.0, 100.0);
- v[CPU_METER_FREQUENCY] = NAN;
- v[CPU_METER_TEMPERATURE] = NAN;
+ v[CPU_METER_FREQUENCY] = cpuData->frequency;
+ v[CPU_METER_TEMPERATURE] = cpuData->temperature;
return percent;
}

© 2014-2024 Faster IT GmbH | imprint | privacy policy