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
26 changes: 17 additions & 9 deletions Action.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ in the source distribution for its full text.
#include "ListItem.h"
#include "Macros.h"
#include "MainPanel.h"
#include "MemoryMeter.h"
#include "OpenFilesScreen.h"
#include "Platform.h"
#include "Process.h"
#include "ProcessLocksScreen.h"
#include "ProvideCurses.h"
Expand Down Expand Up @@ -750,16 +752,22 @@ static Htop_Reaction actionHelp(State* st) {
attrset(CRT_colors[DEFAULT_COLOR]);
mvaddstr(line++, 0, "Memory bar: ");
addattrstr(CRT_colors[BAR_BORDER], "[");
addbartext(CRT_colors[MEMORY_USED], "", "used");
addbartext(CRT_colors[MEMORY_SHARED], "/", "shared");
addbartext(CRT_colors[MEMORY_COMPRESSED], "/", "compressed");
if (st->host->settings->showCachedMemory) {
addbartext(CRT_colors[MEMORY_BUFFERS_TEXT], "/", "buffers");
addbartext(CRT_colors[MEMORY_CACHE], "/", "cache");
addbartext(CRT_colors[BAR_SHADOW], " ", "used");
} else {
addbartext(CRT_colors[BAR_SHADOW], " ", "used");
// memory classes are OS-specific and provided in their <os>/Platform.c implementation
// ideal length of memory bar == 56 chars. Any length < 45 requires padding to 45.
// [0 1 2 3 4 5 ]
// [12345678901234567890123456789012345678901234567890123456]
// [ ^ 5 ]
// [class1/class2/class3/.../classN used/total]
int barTxtLen = 0;
for (unsigned int i = 0; i < Platform_numberOfMemoryClasses; i++) {
if (!st->host->settings->showCachedMemory && Platform_memoryClasses[i].countsAsCache)
continue; // skip reclaimable cache memory classes if "show cached memory" is not ticked
addbartext(CRT_colors[Platform_memoryClasses[i].color], (i == 0 ? "" : "/"), Platform_memoryClasses[i].label);
barTxtLen += (i == 0 ? 0 : 1) + strlen (Platform_memoryClasses[i].label);
}
for (int i = barTxtLen; i < 45; i++)
addattrstr(CRT_colors[BAR_SHADOW], " "); // pad to 45 chars if necessary
addbartext(CRT_colors[BAR_SHADOW], " ", "used");
addbartext(CRT_colors[BAR_SHADOW], "/", "total");
addattrstr(CRT_colors[BAR_BORDER], "]");

Expand Down
84 changes: 42 additions & 42 deletions CRT.c
Original file line number Diff line number Diff line change
Expand Up @@ -177,12 +177,12 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[SWAP_FRONTSWAP] = A_BOLD | ColorPairGrayBlack,
[GRAPH_1] = A_BOLD | ColorPair(Cyan, Black),
[GRAPH_2] = ColorPair(Cyan, Black),
[MEMORY_USED] = ColorPair(Green, Black),
[MEMORY_BUFFERS] = A_BOLD | ColorPair(Blue, Black),
[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Blue, Black),
[MEMORY_CACHE] = ColorPair(Yellow, Black),
[MEMORY_SHARED] = ColorPair(Magenta, Black),
[MEMORY_COMPRESSED] = A_BOLD | ColorPairGrayBlack,
[MEMORY_1] = ColorPair(Green, Black),
[MEMORY_2] = A_BOLD | ColorPair(Blue, Black),
[MEMORY_3] = ColorPair(Yellow, Black),
[MEMORY_4] = ColorPair(Magenta, Black),
[MEMORY_5] = A_BOLD | ColorPairGrayBlack,
[MEMORY_6] = ColorPair(Red, Black),
[HUGEPAGE_1] = ColorPair(Green, Black),
[HUGEPAGE_2] = ColorPair(Yellow, Black),
[HUGEPAGE_3] = ColorPair(Red, Black),
Expand Down Expand Up @@ -295,12 +295,12 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[SWAP_FRONTSWAP] = A_DIM,
[GRAPH_1] = A_BOLD,
[GRAPH_2] = A_NORMAL,
[MEMORY_USED] = A_BOLD,
[MEMORY_BUFFERS] = A_NORMAL,
[MEMORY_BUFFERS_TEXT] = A_NORMAL,
[MEMORY_CACHE] = A_NORMAL,
[MEMORY_SHARED] = A_NORMAL,
[MEMORY_COMPRESSED] = A_DIM,
[MEMORY_1] = A_BOLD,
[MEMORY_2] = A_NORMAL,
[MEMORY_3] = A_NORMAL,
[MEMORY_4] = A_NORMAL,
[MEMORY_5] = A_DIM,
[MEMORY_6] = A_NORMAL,
[HUGEPAGE_1] = A_BOLD,
[HUGEPAGE_2] = A_NORMAL,
[HUGEPAGE_3] = A_REVERSE | A_BOLD,
Expand Down Expand Up @@ -413,12 +413,12 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[SWAP_FRONTSWAP] = A_BOLD | ColorPair(Black, White),
[GRAPH_1] = A_BOLD | ColorPair(Blue, White),
[GRAPH_2] = ColorPair(Blue, White),
[MEMORY_USED] = ColorPair(Green, White),
[MEMORY_BUFFERS] = ColorPair(Cyan, White),
[MEMORY_BUFFERS_TEXT] = ColorPair(Cyan, White),
[MEMORY_CACHE] = ColorPair(Yellow, White),
[MEMORY_SHARED] = ColorPair(Magenta, White),
[MEMORY_COMPRESSED] = A_BOLD | ColorPair(Black, White),
[MEMORY_1] = ColorPair(Green, White),
[MEMORY_2] = ColorPair(Cyan, White),
[MEMORY_3] = ColorPair(Yellow, White),
[MEMORY_4] = ColorPair(Magenta, White),
[MEMORY_5] = A_BOLD | ColorPair(Black, White),
[MEMORY_6] = ColorPair(Red, White),
[HUGEPAGE_1] = ColorPair(Green, White),
[HUGEPAGE_2] = ColorPair(Yellow, White),
[HUGEPAGE_3] = ColorPair(Red, White),
Expand Down Expand Up @@ -531,12 +531,12 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[SWAP_FRONTSWAP] = ColorPairGrayBlack,
[GRAPH_1] = A_BOLD | ColorPair(Cyan, Black),
[GRAPH_2] = ColorPair(Cyan, Black),
[MEMORY_USED] = ColorPair(Green, Black),
[MEMORY_BUFFERS] = ColorPair(Cyan, Black),
[MEMORY_BUFFERS_TEXT] = ColorPair(Cyan, Black),
[MEMORY_CACHE] = ColorPair(Yellow, Black),
[MEMORY_SHARED] = ColorPair(Magenta, Black),
[MEMORY_COMPRESSED] = ColorPairGrayBlack,
[MEMORY_1] = ColorPair(Green, Black),
[MEMORY_2] = ColorPair(Cyan, Black),
[MEMORY_3] = ColorPair(Yellow, Black),
[MEMORY_4] = ColorPair(Magenta, Black),
[MEMORY_5] = ColorPairGrayBlack,
[MEMORY_6] = ColorPair(Red, Black),
[HUGEPAGE_1] = ColorPair(Green, Black),
[HUGEPAGE_2] = ColorPair(Yellow, Black),
[HUGEPAGE_3] = ColorPair(Red, Black),
Expand Down Expand Up @@ -649,12 +649,12 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[SWAP_FRONTSWAP] = A_BOLD | ColorPair(Black, Blue),
[GRAPH_1] = A_BOLD | ColorPair(Cyan, Blue),
[GRAPH_2] = ColorPair(Cyan, Blue),
[MEMORY_USED] = A_BOLD | ColorPair(Green, Blue),
[MEMORY_BUFFERS] = A_BOLD | ColorPair(Cyan, Blue),
[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Cyan, Blue),
[MEMORY_CACHE] = A_BOLD | ColorPair(Yellow, Blue),
[MEMORY_SHARED] = A_BOLD | ColorPair(Magenta, Blue),
[MEMORY_COMPRESSED] = A_BOLD | ColorPair(Black, Blue),
[MEMORY_1] = A_BOLD | ColorPair(Green, Blue),
[MEMORY_2] = A_BOLD | ColorPair(Cyan, Blue),
[MEMORY_3] = A_BOLD | ColorPair(Yellow, Blue),
[MEMORY_4] = A_BOLD | ColorPair(Magenta, Blue),
[MEMORY_5] = A_BOLD | ColorPair(Black, Blue),
[MEMORY_6] = A_BOLD | ColorPair(Red, Blue),
[HUGEPAGE_1] = A_BOLD | ColorPair(Green, Blue),
[HUGEPAGE_2] = A_BOLD | ColorPair(Yellow, Blue),
[HUGEPAGE_3] = A_BOLD | ColorPair(Red, Blue),
Expand Down Expand Up @@ -767,12 +767,12 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[SWAP_FRONTSWAP] = ColorPair(Yellow, Black),
[GRAPH_1] = A_BOLD | ColorPair(Green, Black),
[GRAPH_2] = ColorPair(Green, Black),
[MEMORY_USED] = ColorPair(Green, Black),
[MEMORY_BUFFERS] = ColorPair(Blue, Black),
[MEMORY_BUFFERS_TEXT] = A_BOLD | ColorPair(Blue, Black),
[MEMORY_CACHE] = ColorPair(Yellow, Black),
[MEMORY_SHARED] = ColorPair(Magenta, Black),
[MEMORY_COMPRESSED] = ColorPair(Yellow, Black),
[MEMORY_1] = ColorPair(Green, Black),
[MEMORY_2] = ColorPair(Blue, Black),
[MEMORY_3] = ColorPair(Yellow, Black),
[MEMORY_4] = ColorPair(Magenta, Black),
[MEMORY_5] = ColorPair(Yellow, Black),
[MEMORY_6] = ColorPair(Red, Black),
[HUGEPAGE_1] = ColorPair(Green, Black),
[HUGEPAGE_2] = ColorPair(Yellow, Black),
[HUGEPAGE_3] = ColorPair(Red, Black),
Expand Down Expand Up @@ -880,12 +880,12 @@ static int CRT_colorSchemes[LAST_COLORSCHEME][LAST_COLORELEMENT] = {
[SWAP_FRONTSWAP] = A_BOLD | ColorPairGrayBlack,
[GRAPH_1] = A_BOLD,
[GRAPH_2] = A_NORMAL,
[MEMORY_USED] = A_BOLD | ColorPair(Yellow, Black),
[MEMORY_BUFFERS] = A_NORMAL,
[MEMORY_BUFFERS_TEXT] = A_NORMAL,
[MEMORY_CACHE] = A_NORMAL,
[MEMORY_SHARED] = A_NORMAL,
[MEMORY_COMPRESSED] = A_BOLD | ColorPairGrayBlack,
[MEMORY_1] = A_BOLD | ColorPair(Yellow, Black),
[MEMORY_2] = A_NORMAL,
[MEMORY_3] = A_NORMAL,
[MEMORY_4] = A_NORMAL,
[MEMORY_5] = A_BOLD | ColorPairGrayBlack,
[MEMORY_6] = A_NORMAL,
[HUGEPAGE_1] = A_BOLD,
[HUGEPAGE_2] = A_NORMAL,
[HUGEPAGE_3] = A_BOLD | ColorPair(Cyan, Black),
Expand Down
12 changes: 6 additions & 6 deletions CRT.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,12 @@ typedef enum ColorElements_ {
BAR_SHADOW,
GRAPH_1,
GRAPH_2,
MEMORY_USED,
MEMORY_BUFFERS,
MEMORY_BUFFERS_TEXT,
MEMORY_CACHE,
MEMORY_SHARED,
MEMORY_COMPRESSED,
MEMORY_1,
MEMORY_2,
MEMORY_3,
MEMORY_4,
MEMORY_5,
MEMORY_6,
HUGEPAGE_1,
HUGEPAGE_2,
HUGEPAGE_3,
Expand Down
5 changes: 0 additions & 5 deletions Machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,6 @@ typedef struct Machine_ {
#endif

memory_t totalMem;
memory_t usedMem;
memory_t buffersMem;
memory_t cachedMem;
memory_t sharedMem;
memory_t availableMem;

memory_t totalSwap;
memory_t usedSwap;
Expand Down
90 changes: 36 additions & 54 deletions MemoryMeter.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/*
htop - MemoryMeter.c
(C) 2004-2011 Hisham H. Muhammad
(C) 2025 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/
Expand All @@ -21,11 +22,12 @@ in the source distribution for its full text.


static const int MemoryMeter_attributes[] = {
MEMORY_USED,
MEMORY_SHARED,
MEMORY_COMPRESSED,
MEMORY_BUFFERS,
MEMORY_CACHE
MEMORY_1,
MEMORY_2,
MEMORY_3,
MEMORY_4,
MEMORY_5,
MEMORY_6

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I preferred when explicit color names were used (DYNAMIC_RED, etc). Explicit color names gave at least a chance for the contributors wishing to bring in support for another platform to map the same colors to roughly equivalent memory classes where that possibility exist, and use other colors where it doesn't. Having numbered opaque names is uninformative and thus unhelpful IMO. If you don't want explicit color names, perhaps give more descriptive labels that correspond to the ASCII character that's drawn by ncurses on monochrome terminals. e.g. MEMORY_CHAR_HASH, MEMORY_CHAR_DOLLAR, etc. It makes tracking similar choices easier.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PierreMarieBaty The ASCII characters drawn in monochrome mode of htop is not assigned by ncurses, but by htop itself. The character list is defined in Meter.c.

};

static void MemoryMeter_updateValues(Meter* this) {
Expand All @@ -35,26 +37,28 @@ static void MemoryMeter_updateValues(Meter* this) {

Settings *settings = this->host->settings;

/* shared, compressed and available memory are not supported on all platforms */
this->values[MEMORY_METER_SHARED] = NAN;
this->values[MEMORY_METER_COMPRESSED] = NAN;
this->values[MEMORY_METER_AVAILABLE] = NAN;
/* not all memory classes are supported on all platforms */
for (unsigned int memoryClassIdx = 0; memoryClassIdx < Platform_numberOfMemoryClasses; memoryClassIdx++) {
this->values[memoryClassIdx] = NAN;
}

Platform_setMemoryValues(this);
this->curItems = (uint8_t) Platform_numberOfMemoryClasses;

/* compute the used memory */
double used = 0.0;
for (unsigned int memoryClassIdx = 0; memoryClassIdx < Platform_numberOfMemoryClasses; memoryClassIdx++) {
if (Platform_memoryClasses[memoryClassIdx].countsAsUsed)
used += this->values[memoryClassIdx];
}
Comment on lines +50 to +53
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer with all braces to be consistent with below:

Suggested change
for (unsigned int memoryClassIdx = 0; memoryClassIdx < Platform_numberOfMemoryClasses; memoryClassIdx++) {
if (Platform_memoryClasses[memoryClassIdx].countsAsUsed)
used += this->values[memoryClassIdx];
}
for (unsigned int memoryClassIdx = 0; memoryClassIdx < Platform_numberOfMemoryClasses; memoryClassIdx++) {
if (Platform_memoryClasses[memoryClassIdx].countsAsUsed) {
used += this->values[memoryClassIdx];
}
}


/* clear the values we don't want to see */
if ((this->mode == GRAPH_METERMODE || this->mode == BAR_METERMODE) && !settings->showCachedMemory) {
this->values[MEMORY_METER_BUFFERS] = 0;
this->values[MEMORY_METER_CACHE] = 0;
for (unsigned int memoryClassIdx = 0; memoryClassIdx < Platform_numberOfMemoryClasses; memoryClassIdx++) {
if (Platform_memoryClasses[memoryClassIdx].countsAsCache)
this->values[memoryClassIdx] = NAN;
}
Comment on lines +57 to +60
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (unsigned int memoryClassIdx = 0; memoryClassIdx < Platform_numberOfMemoryClasses; memoryClassIdx++) {
if (Platform_memoryClasses[memoryClassIdx].countsAsCache)
this->values[memoryClassIdx] = NAN;
}
for (unsigned int memoryClassIdx = 0; memoryClassIdx < Platform_numberOfMemoryClasses; memoryClassIdx++) {
if (Platform_memoryClasses[memoryClassIdx].countsAsCache) {
this->values[memoryClassIdx] = NAN;
}
}

}
/* Do not print available memory in bar mode */
static_assert(MEMORY_METER_AVAILABLE + 1 == MEMORY_METER_ITEMCOUNT,
"MEMORY_METER_AVAILABLE is not the last item in MemoryMeterValues");
this->curItems = MEMORY_METER_AVAILABLE;

/* we actually want to show "used + shared + compressed" */
double used = this->values[MEMORY_METER_USED];
if (isPositive(this->values[MEMORY_METER_SHARED]))
used += this->values[MEMORY_METER_SHARED];
if (isPositive(this->values[MEMORY_METER_COMPRESSED]))
used += this->values[MEMORY_METER_COMPRESSED];

written = Meter_humanUnit(buffer, used, size);
METER_BUFFER_CHECK(buffer, size, written);
Expand All @@ -73,37 +77,15 @@ static void MemoryMeter_display(const Object* cast, RichString* out) {
Meter_humanUnit(buffer, this->total, sizeof(buffer));
RichString_appendAscii(out, CRT_colors[METER_VALUE], buffer);

Meter_humanUnit(buffer, this->values[MEMORY_METER_USED], sizeof(buffer));
RichString_appendAscii(out, CRT_colors[METER_TEXT], " used:");
RichString_appendAscii(out, CRT_colors[MEMORY_USED], buffer);

/* shared memory is not supported on all platforms */
if (isNonnegative(this->values[MEMORY_METER_SHARED])) {
Meter_humanUnit(buffer, this->values[MEMORY_METER_SHARED], sizeof(buffer));
RichString_appendAscii(out, CRT_colors[METER_TEXT], " shared:");
RichString_appendAscii(out, CRT_colors[MEMORY_SHARED], buffer);
}

/* compressed memory is not supported on all platforms */
if (isNonnegative(this->values[MEMORY_METER_COMPRESSED])) {
Meter_humanUnit(buffer, this->values[MEMORY_METER_COMPRESSED], sizeof(buffer));
RichString_appendAscii(out, CRT_colors[METER_TEXT], " compressed:");
RichString_appendAscii(out, CRT_colors[MEMORY_COMPRESSED], buffer);
}

Meter_humanUnit(buffer, this->values[MEMORY_METER_BUFFERS], sizeof(buffer));
RichString_appendAscii(out, settings->showCachedMemory ? CRT_colors[METER_TEXT] : CRT_colors[METER_SHADOW], " buffers:");
RichString_appendAscii(out, settings->showCachedMemory ? CRT_colors[MEMORY_BUFFERS_TEXT] : CRT_colors[METER_SHADOW], buffer);

Meter_humanUnit(buffer, this->values[MEMORY_METER_CACHE], sizeof(buffer));
RichString_appendAscii(out, settings->showCachedMemory ? CRT_colors[METER_TEXT] : CRT_colors[METER_SHADOW], " cache:");
RichString_appendAscii(out, settings->showCachedMemory ? CRT_colors[MEMORY_CACHE] : CRT_colors[METER_SHADOW], buffer);

/* available memory is not supported on all platforms */
if (isNonnegative(this->values[MEMORY_METER_AVAILABLE])) {
Meter_humanUnit(buffer, this->values[MEMORY_METER_AVAILABLE], sizeof(buffer));
RichString_appendAscii(out, CRT_colors[METER_TEXT], " available:");
RichString_appendAscii(out, CRT_colors[METER_VALUE], buffer);
/* print the memory classes in the order supplied (specific to each platform) */
for (unsigned int memoryClassIdx = 0; memoryClassIdx < Platform_numberOfMemoryClasses; memoryClassIdx++) {
if (!settings->showCachedMemory && Platform_memoryClasses[memoryClassIdx].countsAsCache)
continue; // skip reclaimable cache memory classes if "show cached memory" is not ticked
Comment on lines +82 to +83
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some visual space doesn't hurt ^^

Suggested change
if (!settings->showCachedMemory && Platform_memoryClasses[memoryClassIdx].countsAsCache)
continue; // skip reclaimable cache memory classes if "show cached memory" is not ticked
if (!settings->showCachedMemory && Platform_memoryClasses[memoryClassIdx].countsAsCache)
continue; // skip reclaimable cache memory classes if "show cached memory" is not ticked

Meter_humanUnit(buffer, this->values[memoryClassIdx], sizeof(buffer));
RichString_appendAscii(out, CRT_colors[METER_TEXT], " ");
RichString_appendAscii(out, CRT_colors[METER_TEXT], Platform_memoryClasses[memoryClassIdx].label);
RichString_appendAscii(out, CRT_colors[METER_TEXT], ":");
RichString_appendAscii(out, CRT_colors[Platform_memoryClasses[memoryClassIdx].color], buffer);
}
}

Expand All @@ -116,7 +98,7 @@ const MeterClass MemoryMeter_class = {
.updateValues = MemoryMeter_updateValues,
.defaultMode = BAR_METERMODE,
.supportedModes = METERMODE_DEFAULT_SUPPORTED,
.maxItems = MEMORY_METER_ITEMCOUNT,
.maxItems = 6, // maximum of MEMORY_N settings
.isPercentChart = true,
.total = 100.0,
.attributes = MemoryMeter_attributes,
Expand Down
16 changes: 7 additions & 9 deletions MemoryMeter.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,21 +3,19 @@
/*
htop - MemoryMeter.h
(C) 2004-2011 Hisham H. Muhammad
(C) 2025 htop dev team
Released under the GNU GPLv2+, see the COPYING file
in the source distribution for its full text.
*/

#include "Meter.h"

typedef enum {
MEMORY_METER_USED = 0,
MEMORY_METER_SHARED = 1,
MEMORY_METER_COMPRESSED = 2,
MEMORY_METER_BUFFERS = 3,
MEMORY_METER_CACHE = 4,
MEMORY_METER_AVAILABLE = 5,
MEMORY_METER_ITEMCOUNT = 6, // number of entries in this enum
} MemoryMeterValues;
typedef struct MemoryClass_s {
const char *label; // e.g. "wired", "shared", "compressed" - platform-specific memory classe names
bool countsAsUsed; // memory class counts as "used" memory
bool countsAsCache; // memory class reclaimed under pressure (displayed with "show cached memory")
ColorElements color; // one of the MEMORY CRT color values
} MemoryClass;

extern const MeterClass MemoryMeter_class;

Expand Down
8 changes: 0 additions & 8 deletions darwin/DarwinMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,19 +60,11 @@ static unsigned int DarwinMachine_allocateCPULoadInfo(processor_cpu_load_info_t*
}

static void DarwinMachine_getVMStats(DarwinMachine* this) {
#ifdef HAVE_STRUCT_VM_STATISTICS64
mach_msg_type_number_t info_size = HOST_VM_INFO64_COUNT;

if (host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info_t)&this->vm_stats, &info_size) != 0) {
CRT_fatalError("Unable to retrieve VM statistics64");
}
#else
mach_msg_type_number_t info_size = HOST_VM_INFO_COUNT;

if (host_statistics(mach_host_self(), HOST_VM_INFO, (host_info_t)&this->vm_stats, &info_size) != 0) {
CRT_fatalError("Unable to retrieve VM statistics");
}
#endif
Comment on lines -63 to -75
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How does this affect the baseline OS requirements?

Also, can we split off this change into its own commit to make reviewing this change easier?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We have someone who wants to port htop to iOS 6 (PR #1828) recently. And I don't like this PR contains changes that unnecessarily bump Darwin OS requirements.

I bet Nathan (@natoscott) and Pierre-Marie don't have the idea what they're doing. This doesn't count the fact that the memory display now becomes different from what's displayed in macOS top. (this comment)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you bet I have no idea what I'm doing, I could claim I know you don't have the skill level to understand most of what is being discussed here - your inaptitude to understand the problem being the only proof I need. See? I too can make derogatory comments: admire how it adds constructively to the discussion. Want to continue? I'd have plenty of things to say on the way you manage benevolent contributions to your project from other people, of which a psychoanalyst would likely diagnose a certain sense of intellectual insecurity. How does it feel? Want to continue again? Or we stop here and engage in a more productive conversation?

Facts.

  1. Darwin vm_statistics64 was introduced in OS/X Snow Leopard in 2009, that is - 16 years ago.
  2. At the time when I sent this code to Nathan Scott, no iOS branch existed in htop's source code, and more generally no 32-bit build for Darwin was possible. I logically concluded this #ifdef was the reliquate of an age long gone and could be disposed of, especially considering the temper tantrum you made about #ifdefs when I suggested to add some for FreeBSD in your platform-agnostic code. And guess what: I even supposed it would please you.
  3. You are unable to ascertain precisely the baseline OS requirement for all of the htop's ports because they are documented nowhere. The best you can come up with is "try building it, if it works that's okay, if it doesn't we'll look into it", and now you are arguing against removing support for a version of the Darwin kernel that's obsolete for more than a decade? Continue entertaining the readers with your posts. At this point, why not bring back support for paleolithic kernels in all the other branches, Linux, FreeBSD, NetBSD?

Now on a more professional tone. This deletion was made in a spirit of simplification. If adding 32-bit iOS support to the htop code should be considered, then simply put these #ifdefs back. No need to insult or defame the contributors.

One last remark: if someone wants in Q4 2025 to add support to an ancient version of an OS on a deprecated architecture, he/she likely already has the skills to do it himself and add the missing pieces back. Any code that's #ifdef'ed out 99% of the time the project is built and that you leave here for legacy reasons is a technological debt, that you will bear the responsibility to maintain. I could troll you seriously here, with more irony about your role as a maintainer, please note that I choose not to. I expect you to do the same, or adopt the only responsible alternative.

Copy link
Contributor

@Explorer09 Explorer09 Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PierreMarieBaty

Darwin vm_statistics64 was introduced in OS/X Snow Leopard in 2009, that is - 16 years ago.

This deletion was made in a spirit of simplification. If adding 32-bit iOS support to the htop code should be considered, then simply put these #ifdefs back. No need to insult or defame the contributors.

Dropping compatibility to legacy systems without stating a good reason is a bad attitude to many free and open source projects.
We have even had a pull request to make compatibility to OS X Tiger (#1687)! Yes, and that unreasoned drop of the old code is to make the life of other contributors harder!

I'm aware that the legacy code may be a "technological debt", but other than the reasons of "it's broken for a long time" and "it's a substantial effort to maintain the compatibility code that it may not seems worth it", I'm not seeing any other good reason for removing it.

I never support the attitude from those big, proprietary corporations that they can arbitrary drop support for old hardware or systems (look at Microsoft and Windows 11, for example), and expect consumers/end-users to get over it.

Copy link

@PierreMarieBaty PierreMarieBaty Dec 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm aware that the legacy code may be a "technological debt", but other than the reasons of "it's broken for a long time" and "it's a substantial effort to maintain the compatibility code that it may not seems worth it", I'm not seeing any other good reason for removing it.

These are, precisely, two most excellent and self-sufficient, reasons to do it.

But as I said elsewhere, this is your project - you do what you want.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To both of you: Please at least try to stay professional for a moment. (@Explorer09 We had a discussion about these kinds of comments off-site. I'm not here to babysit you and would appreciate if we keep things without personal attacks/insults.)

Back for the actual topic. Personally I'm open to move forward in either direction, without any preference. Thus my initial question in this thread, how dropping the #ifdef affects compatibility. Regardless of what we are going to decide on this question though, this should be its own commit, if we decide to keep it, as it's a change unrelated to the other changes. After all the commit history should tell you about the various changes performed to reach a given goal and squashing this in with the other changes obscures the visibility of this backwards compatibility related change.

Quick aside on the backward compatibility: For the Linux port we intentionally keep support for kernels without support for openat, which was introduced in Linux 2.6.16. And while we do not adhere to strict BC for all eternity, we at least try to maintain BC on a best-effort basis. Thus anything that was around when htop came around is potentially an option for having it supported, if people are actively asking for it AND supporting it doesn't cause other complications elsewhere. The memory structure handling subject of this comment is easy enough to keep around, so there's no pressure to touch that code AFAICS.

}

void Machine_scan(Machine* super) {
Expand Down
4 changes: 0 additions & 4 deletions darwin/DarwinMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ typedef struct DarwinMachine_ {
Machine super;

host_basic_info_data_t host_info;
#ifdef HAVE_STRUCT_VM_STATISTICS64
vm_statistics64_data_t vm_stats;
#else
vm_statistics_data_t vm_stats;
#endif
processor_cpu_load_info_t prev_load;
processor_cpu_load_info_t curr_load;

Expand Down
Loading
Loading