mirror of https://github.com/xzeldon/htop.git
Merge pull request #436 from cgzones/freebsd
FreeBSD: add support for CPU frequency and temperature Tested on two physical systems running FreeBSD 12.1
This commit is contained in:
commit
ee97916fd5
|
@ -79,7 +79,7 @@ static void CPUMeter_updateValues(Meter* this) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_SENSORS_SENSORS_H
|
#ifdef BUILD_WITH_CPU_TEMP
|
||||||
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_SENSORS_SENSORS_H
|
#ifdef BUILD_WITH_CPU_TEMP
|
||||||
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];
|
||||||
|
|
|
@ -118,8 +118,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("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_SENSORS_SENSORS_H
|
#ifdef BUILD_WITH_CPU_TEMP
|
||||||
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU temperature (requires libsensors)", &(settings->showCPUTemperature)));
|
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)));
|
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)));
|
||||||
|
|
|
@ -205,7 +205,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_SENSORS_SENSORS_H
|
#ifdef BUILD_WITH_CPU_TEMP
|
||||||
} 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")) {
|
||||||
|
@ -315,7 +315,7 @@ int Settings_write(const 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_SENSORS_SENSORS_H
|
#ifdef BUILD_WITH_CPU_TEMP
|
||||||
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
|
||||||
|
@ -363,7 +363,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_SENSORS_SENSORS_H
|
#ifdef BUILD_WITH_CPU_TEMP
|
||||||
this->showCPUTemperature = false;
|
this->showCPUTemperature = false;
|
||||||
this->degreeFahrenheit = false;
|
this->degreeFahrenheit = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,7 +41,7 @@ typedef struct Settings_ {
|
||||||
bool detailedCPUTime;
|
bool detailedCPUTime;
|
||||||
bool showCPUUsage;
|
bool showCPUUsage;
|
||||||
bool showCPUFrequency;
|
bool showCPUFrequency;
|
||||||
#ifdef HAVE_SENSORS_SENSORS_H
|
#ifdef BUILD_WITH_CPU_TEMP
|
||||||
bool showCPUTemperature;
|
bool showCPUTemperature;
|
||||||
bool degreeFahrenheit;
|
bool degreeFahrenheit;
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -509,6 +509,9 @@ case "$enable_sensors" in
|
||||||
AC_MSG_ERROR([bad value '$enable_sensors' for --enable-sensors])
|
AC_MSG_ERROR([bad value '$enable_sensors' for --enable-sensors])
|
||||||
;;
|
;;
|
||||||
esac
|
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
|
||||||
|
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@ in the source distribution for its full text.
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <math.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/_iovec.h>
|
#include <sys/_iovec.h>
|
||||||
|
@ -171,7 +172,7 @@ void ProcessList_delete(ProcessList* this) {
|
||||||
free(this);
|
free(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void FreeBSDProcessList_scanCPUTime(ProcessList* pl) {
|
static inline void FreeBSDProcessList_scanCPU(ProcessList* pl) {
|
||||||
const FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl;
|
const FreeBSDProcessList* fpl = (FreeBSDProcessList*) pl;
|
||||||
|
|
||||||
int cpus = pl->cpuCount; // actual CPU count
|
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];
|
cpuData->systemAllPercent = cp_time_p[CP_SYS] + cp_time_p[CP_INTR];
|
||||||
// this one is not really used
|
// this one is not really used
|
||||||
//cpuData->idlePercent = cp_time_p[CP_IDLE];
|
//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);
|
openzfs_sysctl_updateArcStats(&fpl->zfs);
|
||||||
FreeBSDProcessList_scanMemoryInfo(super);
|
FreeBSDProcessList_scanMemoryInfo(super);
|
||||||
FreeBSDProcessList_scanCPUTime(super);
|
FreeBSDProcessList_scanCPU(super);
|
||||||
|
|
||||||
// in pause mode only gather global data for meters (CPU/memory/...)
|
// in pause mode only gather global data for meters (CPU/memory/...)
|
||||||
if (pauseProcessUpdate) {
|
if (pauseProcessUpdate) {
|
||||||
|
|
|
@ -23,6 +23,9 @@ typedef struct CPUData_ {
|
||||||
double systemPercent;
|
double systemPercent;
|
||||||
double irqPercent;
|
double irqPercent;
|
||||||
double systemAllPercent;
|
double systemAllPercent;
|
||||||
|
|
||||||
|
double frequency;
|
||||||
|
double temperature;
|
||||||
} CPUData;
|
} CPUData;
|
||||||
|
|
||||||
typedef struct FreeBSDProcessList_ {
|
typedef struct FreeBSDProcessList_ {
|
||||||
|
|
|
@ -209,8 +209,8 @@ double Platform_setCPUValues(Meter* this, int cpu) {
|
||||||
|
|
||||||
percent = CLAMP(percent, 0.0, 100.0);
|
percent = CLAMP(percent, 0.0, 100.0);
|
||||||
|
|
||||||
v[CPU_METER_FREQUENCY] = NAN;
|
v[CPU_METER_FREQUENCY] = cpuData->frequency;
|
||||||
v[CPU_METER_TEMPERATURE] = NAN;
|
v[CPU_METER_TEMPERATURE] = cpuData->temperature;
|
||||||
|
|
||||||
return percent;
|
return percent;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue