Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions Action.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@ in the source distribution for its full text.
#include "ListItem.h"
#include "Macros.h"
#include "MainPanel.h"
#include "NvidiaJetson.h"
#include "OpenFilesScreen.h"
#include "Process.h"
#include "ProcessLocksScreen.h"
#include "ProcessTable.h"
#include "ProvideCurses.h"
#include "Row.h"
#include "RowField.h"
Expand Down Expand Up @@ -646,6 +648,26 @@ static Htop_Reaction actionTogglePauseUpdate(State* st) {
return HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_KEEP_FOLLOWING;
}

#ifdef NVIDIA_JETSON
static Htop_Reaction actionToggleGpuFilter(State* st) {
static Hashtable *stash = NULL;

Hashtable *GpuPidMatchList = NvidiaJetson_GetPidMatchList();
if (GpuPidMatchList) {
st->showGpuProcesses = !st->showGpuProcesses;

ProcessTable *pt = (ProcessTable *)st->host->activeTable;
if (st->showGpuProcesses) {
stash = pt->pidMatchList;
pt->pidMatchList = GpuPidMatchList;
} else {
pt->pidMatchList = stash;
}
}
return HTOP_REFRESH | HTOP_REDRAW_BAR | HTOP_KEEP_FOLLOWING;
}
#endif

static const struct {
const char* key;
bool roInactive;
Expand All @@ -658,6 +680,9 @@ static const struct {
{ .key = " F3 /: ", .roInactive = false, .info = "incremental name search" },
{ .key = " F4 \\: ", .roInactive = false, .info = "incremental name filtering" },
{ .key = " F5 t: ", .roInactive = false, .info = "tree view" },
#ifdef NVIDIA_JETSON
{ .key = " g: ", .roInactive = false, .info = "show GPU processes (root only)" },
#endif
{ .key = " p: ", .roInactive = false, .info = "toggle program path" },
{ .key = " m: ", .roInactive = false, .info = "toggle merged command" },
{ .key = " Z: ", .roInactive = false, .info = "pause/resume process updates" },
Expand Down Expand Up @@ -933,6 +958,9 @@ void Action_setBindings(Htop_Action* keys) {
keys['a'] = actionSetAffinity;
keys['c'] = actionTagAllChildren;
keys['e'] = actionShowEnvScreen;
#ifdef NVIDIA_JETSON
keys['g'] = actionToggleGpuFilter;
#endif
keys['h'] = actionHelp;
keys['k'] = actionKill;
keys['l'] = actionLsof;
Expand Down
3 changes: 3 additions & 0 deletions Action.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ typedef struct State_ {
bool pauseUpdate;
bool hideSelection;
bool hideMeters;
#ifdef NVIDIA_JETSON
bool showGpuProcesses;
#endif
} State;

static inline bool State_hideFunctionBar(const State* st) {
Expand Down
28 changes: 23 additions & 5 deletions CPUMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,33 @@ static void CPUMeter_updateValues(Meter* this) {
}
}

/*
--enable-sensors turns on BUILD_WITH_CPU_TEMP only
--enable-nvidia-jetson turns on both NVIDIA_JETSON and BUILD_WITH_CPU_TEMP
*/
#ifdef BUILD_WITH_CPU_TEMP
if (settings->showCPUTemperature) {
double cpuTemperature = this->values[CPU_METER_TEMPERATURE];
if (isNaN(cpuTemperature))
if (isNaN(cpuTemperature)) {
xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "N/A");
else if (settings->degreeFahrenheit)
xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%3d%sF", (int)(cpuTemperature * 9 / 5 + 32), CRT_degreeSign);
else
xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%d%sC", (int)cpuTemperature, CRT_degreeSign);
} else if (settings->degreeFahrenheit) {
cpuTemperature = convertCelsiusToFahrenheit(cpuTemperature);
/* Fahrenheit scale gives almost x2 more precise value than Celsius scale => no need to show fractional part */
xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%3d%sF", (int)cpuTemperature, CRT_degreeSign);
} else if (settings->showCPUTemperatureFractional) {
/*
- Modern CPUs has temperature sensors which give a precise value with 3 digits in the fractional part,
see hwmon files, e.g. /sys/class/hwmon/hwmon.../temp1_input, one digit in the fractional part is quite
enough right now.
- If your CPU is above 100C - you have a real problem, no need to print it pretty.
- The formatter "%04.1f" guarantees filling zero in the fractional part, e.g. strings like "37.0C" appears,
the side effect is that temperature value '5C' is shown as "05.0C"
*/
xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%04.1f%sC", cpuTemperature, CRT_degreeSign);
} else {
/* if your CPU is above 100C - you have a real problem, no need to print it pretty */
xSnprintf(cpuTemperatureBuffer, sizeof(cpuTemperatureBuffer), "%2d%sC", (int)cpuTemperature, CRT_degreeSign);
}
}
#endif

Expand Down
7 changes: 7 additions & 0 deletions CRT.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[GPU_ENGINE_2] = ColorPair(Yellow, Black),
[GPU_ENGINE_3] = ColorPair(Red, Black),
[GPU_ENGINE_4] = A_BOLD | ColorPair(Blue, Black),
[GPU_FILTER] = A_BOLD | ColorPair(Red, Cyan),
[GPU_RESIDUE] = ColorPair(Magenta, Black),
[PANEL_EDIT] = ColorPair(White, Blue),
[SCREENS_OTH_BORDER] = ColorPair(Blue, Blue),
Expand Down Expand Up @@ -320,6 +321,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[GPU_ENGINE_2] = A_NORMAL,
[GPU_ENGINE_3] = A_REVERSE | A_BOLD,
[GPU_ENGINE_4] = A_REVERSE,
[GPU_FILTER] = A_REVERSE,
[GPU_RESIDUE] = A_BOLD,
[PANEL_EDIT] = A_BOLD,
[SCREENS_OTH_BORDER] = A_DIM,
Expand Down Expand Up @@ -438,6 +440,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[GPU_ENGINE_2] = ColorPair(Yellow, White),
[GPU_ENGINE_3] = ColorPair(Red, White),
[GPU_ENGINE_4] = ColorPair(Blue, White),
[GPU_FILTER] = ColorPair(Blue, White),
[GPU_RESIDUE] = ColorPair(Magenta, White),
[PANEL_EDIT] = ColorPair(White, Blue),
[SCREENS_OTH_BORDER] = A_BOLD | ColorPair(Black, White),
Expand Down Expand Up @@ -556,6 +559,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[GPU_ENGINE_2] = ColorPair(Yellow, Black),
[GPU_ENGINE_3] = ColorPair(Red, Black),
[GPU_ENGINE_4] = ColorPair(Blue, Black),
[GPU_FILTER] = A_BOLD | ColorPair(Yellow, Cyan),
[GPU_RESIDUE] = ColorPair(Magenta, Black),
[PANEL_EDIT] = ColorPair(White, Blue),
[SCREENS_OTH_BORDER] = ColorPair(Blue, Black),
Expand Down Expand Up @@ -674,6 +678,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[GPU_ENGINE_2] = A_BOLD | ColorPair(Yellow, Blue),
[GPU_ENGINE_3] = A_BOLD | ColorPair(Red, Blue),
[GPU_ENGINE_4] = A_BOLD | ColorPair(White, Blue),
[GPU_FILTER] = A_BOLD | ColorPair(White, Cyan),
[GPU_RESIDUE] = A_BOLD | ColorPair(Magenta, Blue),
[PANEL_EDIT] = ColorPair(White, Blue),
[SCREENS_OTH_BORDER] = A_BOLD | ColorPair(Yellow, Blue),
Expand Down Expand Up @@ -790,6 +795,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[GPU_ENGINE_2] = ColorPair(Yellow, Black),
[GPU_ENGINE_3] = ColorPair(Red, Black),
[GPU_ENGINE_4] = ColorPair(Blue, Black),
[GPU_FILTER] = A_BOLD | ColorPair(Yellow, Green),
[GPU_RESIDUE] = ColorPair(Magenta, Black),
[PANEL_EDIT] = ColorPair(White, Cyan),
[SCREENS_OTH_BORDER] = ColorPair(White, Black),
Expand Down Expand Up @@ -905,6 +911,7 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[GPU_ENGINE_2] = A_NORMAL,
[GPU_ENGINE_3] = A_BOLD | ColorPair(Cyan, Black),
[GPU_ENGINE_4] = A_BOLD | ColorPair(Cyan, Black),
[GPU_FILTER] = A_BOLD | ColorPair(Red, Cyan),
[GPU_RESIDUE] = A_BOLD,
[PANEL_EDIT] = A_BOLD,
[SCREENS_OTH_BORDER] = A_BOLD | ColorPairGrayBlack,
Expand Down
1 change: 1 addition & 0 deletions CRT.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ typedef enum ColorElements_ {
GPU_ENGINE_2,
GPU_ENGINE_3,
GPU_ENGINE_4,
GPU_FILTER,
GPU_RESIDUE,
PANEL_EDIT,
SCREENS_OTH_BORDER,
Expand Down
7 changes: 4 additions & 3 deletions DisplayOptionsPanel.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,14 +185,15 @@ DisplayOptionsPanel* DisplayOptionsPanel_new(Settings* settings, ScreenManager*
Panel_add(super, (Object*) CheckItem_newByRef("Also show CPU frequency", &(settings->showCPUFrequency)));
#ifdef BUILD_WITH_CPU_TEMP
Panel_add(super, (Object*) CheckItem_newByRef(
#if defined(HTOP_LINUX)
"Also show CPU temperature (requires libsensors)",
#elif defined(HTOP_FREEBSD)
#if defined(HTOP_FREEBSD) || defined(NVIDIA_JETSON)
"Also show CPU temperature",
#elif defined(HTOP_LINUX)
"Also show CPU temperature (requires libsensors)",
#else
#error Unknown temperature implementation!
#endif
&(settings->showCPUTemperature)));
Panel_add(super, (Object*) CheckItem_newByRef("- Show fractional CPU temperature for Celsius", (&settings->showCPUTemperatureFractional)));
Panel_add(super, (Object*) CheckItem_newByRef("- Show temperature in degree Fahrenheit instead of Celsius", &(settings->degreeFahrenheit)));
#endif
Panel_add(super, (Object*) CheckItem_newByRef("Show cached memory in graph and bar modes", &(settings->showCachedMemory)));
Expand Down
6 changes: 6 additions & 0 deletions MainPanel.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,12 @@ static void MainPanel_drawFunctionBar(Panel* super, bool hideFunctionBar) {
} else if (this->state->failedUpdate) {
FunctionBar_append(this->state->failedUpdate, CRT_colors[FAILED_READ]);
}

#ifdef NVIDIA_JETSON
if (this->state->showGpuProcesses) {
FunctionBar_append("GPU", CRT_colors[GPU_FILTER]);
}
#endif
}

static void MainPanel_printHeader(Panel* super) {
Expand Down
5 changes: 5 additions & 0 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,11 @@ linux_platform_sources = \
zfs/ZfsArcMeter.c \
zfs/ZfsCompressedArcMeter.c

if NVIDIA_JETSON
linux_platform_headers += linux/NvidiaJetson.h
linux_platform_sources += linux/NvidiaJetson.c
endif

if HAVE_DELAYACCT
linux_platform_headers += linux/LibNl.h
linux_platform_sources += linux/LibNl.c
Expand Down
4 changes: 4 additions & 0 deletions Settings.c
Original file line number Diff line number Diff line change
Expand Up @@ -472,6 +472,8 @@ static bool Settings_read(Settings* this, const char* fileName, const Machine* 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], "show_cpu_temperature_fractional")) {
this->showCPUTemperatureFractional = atoi(option[1]);
} else if (String_eq(option[0], "degree_fahrenheit")) {
this->degreeFahrenheit = atoi(option[1]);
#endif
Expand Down Expand Up @@ -703,6 +705,7 @@ int Settings_write(const Settings* this, bool onCrash) {
printSettingInteger("show_cpu_frequency", this->showCPUFrequency);
#ifdef BUILD_WITH_CPU_TEMP
printSettingInteger("show_cpu_temperature", this->showCPUTemperature);
printSettingInteger("show_cpu_temperature_fractional", this->showCPUTemperatureFractional);
printSettingInteger("degree_fahrenheit", this->degreeFahrenheit);
#endif
printSettingInteger("show_cached_memory", this->showCachedMemory);
Expand Down Expand Up @@ -808,6 +811,7 @@ Settings* Settings_new(const Machine* host, Hashtable* dynamicMeters, Hashtable*
this->showCPUFrequency = false;
#ifdef BUILD_WITH_CPU_TEMP
this->showCPUTemperature = false;
this->showCPUTemperatureFractional = false;
this->degreeFahrenheit = false;
#endif
this->showCachedMemory = true;
Expand Down
1 change: 1 addition & 0 deletions Settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef struct Settings_ {
bool showCPUFrequency;
#ifdef BUILD_WITH_CPU_TEMP
bool showCPUTemperature;
bool showCPUTemperatureFractional;
bool degreeFahrenheit;
#endif
bool showProgramPath;
Expand Down
27 changes: 27 additions & 0 deletions XUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ in the source distribution for its full text.
#include <dirent.h>
#include <stdbool.h>
#include <stddef.h> // IWYU pragma: keep
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h> // IWYU pragma: keep
#include <string.h> // IWYU pragma: keep
Expand Down Expand Up @@ -123,6 +124,13 @@ char* xStrndup(const char* str, size_t len);

ATTR_NONNULL ATTR_ACCESS3_W(2, 3)
ssize_t xReadfile(const char* pathname, void* buffer, size_t count);

ATTR_NONNULL ATTR_ACCESS3_W(2, 3)
static inline double xReadNumberFile(const char *pathname, char *buf, const size_t len) {
ssize_t nread = xReadfile(pathname, buf, len);
return nread > 0 ? strtod(buf, NULL) : NAN;
}

ATTR_NONNULL ATTR_ACCESS3_W(3, 4)
ssize_t xReadfileat(openat_arg_t dirfd, const char* pathname, void* buffer, size_t count);

Expand Down Expand Up @@ -178,4 +186,23 @@ static inline int xDirfd(DIR* dirp) {
return r;
}

static inline double convertCelsiusToFahrenheit(const double celsius) {
return celsius * 9 / 5 + 32;
}

static inline uint64_t fast_strtoull_dec(char** str, int maxlen) {
uint64_t result = 0;

if (!maxlen)
maxlen = 20; // length of maximum value of 18446744073709551615

while (maxlen-- && **str >= '0' && **str <= '9') {
result *= 10;
result += **str - '0';
(*str)++;
}

return result;
}

#endif
43 changes: 42 additions & 1 deletion configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -1171,7 +1171,47 @@ 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_ARG_ENABLE([nvidia-jetson],
[AS_HELP_STRING([--enable-nvidia-jetson],
[enable nvidia jetson support @<:@default=check@:>@])],
[],
[enable_nvidia_jetson=check])
case "$enable_nvidia_jetson" in
no)
;;
check)
if test -f "/etc/nv_tegra_release"; then
if grep -q "BOARD" "/etc/nv_tegra_release"; then
enable_nvidia_jetson=yes
fi
fi
;;
yes)
if test -f "/etc/nv_tegra_release"; then
if grep -q "BOARD" "/etc/nv_tegra_release"; then
enable_nvidia_jetson=yes
else
enable_nvidia_jetson=no
fi
else
enable_nvidia_jetson=no
fi
;;
*)
AC_MSG_ERROR([bad value '$enable_nvidia_jetson' for --enable-nvidia-jetson])
;;
esac

if test "$enable_nvidia_jetson" = yes; then
AC_DEFINE([NVIDIA_JETSON], [1], [Detected correct NVIDIA Jetson board])
else
AC_MSG_NOTICE([This is not a NVIDIA Jetson board])
fi

AM_CONDITIONAL([NVIDIA_JETSON], [test "$enable_nvidia_jetson" = yes])

if test "$enable_sensors" = yes || test "$my_htop_platform" = freebsd || test "$enable_nvidia_jetson" = yes; then
AC_DEFINE([BUILD_WITH_CPU_TEMP], [1], [Define if CPU temperature option should be enabled.])
fi

Expand Down Expand Up @@ -1309,6 +1349,7 @@ AC_MSG_RESULT([
(Linux) delay accounting: $enable_delayacct
(Linux) sensors: $enable_sensors
(Linux) capabilities: $enable_capabilities
(Linux) nvidia-jeston: $enable_nvidia_jetson
unicode: $enable_unicode
affinity: $enable_affinity
unwind: $enable_unwind
Expand Down
10 changes: 9 additions & 1 deletion linux/LinuxMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ in the source distribution for its full text.
#include "UsersTable.h"
#include "XUtils.h"

#include "linux/NvidiaJetson.h"
#include "linux/Platform.h" // needed for GNU/hurd to get PATH_MAX // IWYU pragma: keep

#ifdef HAVE_SENSORS_SENSORS_H
Expand Down Expand Up @@ -746,7 +747,10 @@ void Machine_scan(Machine* super) {
)
LinuxMachine_scanCPUFrequency(this);

#ifdef HAVE_SENSORS_SENSORS_H
#ifdef NVIDIA_JETSON
if (settings->showCPUTemperature)
NvidiaJetson_getCPUTemperatures(this->cpuData, super->existingCPUs);
#elif defined(HAVE_SENSORS_SENSORS_H)
if (settings->showCPUTemperature)
LibSensors_getCPUTemperatures(this->cpuData, super->existingCPUs, super->activeCPUs);
#endif
Expand Down Expand Up @@ -792,6 +796,10 @@ Machine* Machine_new(UsersTable* usersTable, uid_t userId) {
// Initialize CPU count
LinuxMachine_updateCPUcount(this);

#ifdef NVIDIA_JETSON
NvidiaJetson_FindSensors();
#endif

#ifdef HAVE_SENSORS_SENSORS_H
// Fetch CPU topology
LinuxMachine_fetchCPUTopologyFromCPUinfo(this);
Expand Down
5 changes: 3 additions & 2 deletions linux/LinuxMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@ typedef struct CPUData_ {

double frequency;

#ifdef HAVE_SENSORS_SENSORS_H
#ifdef BUILD_WITH_CPU_TEMP
double temperature;

#endif
#ifdef HAVE_SENSORS_SENSORS_H
int physicalID; /* different for each CPU socket */
int coreID; /* same for hyperthreading */
int ccdID; /* same for each AMD chiplet */
Expand Down
Loading