-
-
Notifications
You must be signed in to change notification settings - Fork 547
Corrections to the MemoryMeter for all non-Linux platforms #1824
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| 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. | ||||||||||||||||||||
| */ | ||||||||||||||||||||
|
|
@@ -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 | ||||||||||||||||||||
| }; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| static void MemoryMeter_updateValues(Meter* this) { | ||||||||||||||||||||
|
|
@@ -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
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Prefer with all braces to be consistent with below:
Suggested change
|
||||||||||||||||||||
|
|
||||||||||||||||||||
| /* 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
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||
| } | ||||||||||||||||||||
| /* 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); | ||||||||||||||||||||
|
|
@@ -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
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Some visual space doesn't hurt ^^
Suggested change
|
||||||||||||||||||||
| 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); | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -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, | ||||||||||||||||||||
|
|
||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) There was a problem hiding this comment. Choose a reason for hiding this commentThe 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.
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.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Dropping compatibility to legacy systems without stating a good reason is a bad attitude to many free and open source projects. 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
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.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 Quick aside on the backward compatibility: For the Linux port we intentionally keep support for kernels without support for |
||
| } | ||
|
|
||
| void Machine_scan(Machine* super) { | ||
|
|
||
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.