Skip to content
Closed
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
35 changes: 13 additions & 22 deletions MemoryMeter.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,30 +33,17 @@ static void MemoryMeter_updateValues(Meter* this) {
size_t size = sizeof(this->txtBuffer);
int written;

Settings *settings = this->host->settings;
this->curItems = ARRAYSIZE(MemoryMeter_attributes);

/* 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;
Platform_setMemoryValues(this);
if ((this->mode == GRAPH_METERMODE || this->mode == BAR_METERMODE) && !settings->showCachedMemory) {
this->values[MEMORY_METER_BUFFERS] = 0;
this->values[MEMORY_METER_CACHE] = 0;
}
/* 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);

double totalUsed = 0;
Platform_setMemoryValues(this, &totalUsed);

written = Meter_humanUnit(buffer, totalUsed, size);
METER_BUFFER_CHECK(buffer, size, written);

METER_BUFFER_APPEND_CHR(buffer, size, '/');
Expand Down Expand Up @@ -91,9 +78,13 @@ static void MemoryMeter_display(const Object* cast, RichString* out) {
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);
/* 'buffers' memory field might be hidden by a setting in some OS
ports (e.g. FreeBSD). */
if (isNonnegative(this->values[MEMORY_METER_BUFFERS])) {
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:");
Expand Down
16 changes: 15 additions & 1 deletion darwin/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ void Platform_setGPUValues(Meter* mtr, double* totalUsage, unsigned long long* t
mtr->values[0] = *totalUsage;
}

void Platform_setMemoryValues(Meter* mtr) {
void Platform_setMemoryValues(Meter* mtr, double* totalUsed) {
const DarwinMachine* dhost = (const DarwinMachine*) mtr->host;
#ifdef HAVE_STRUCT_VM_STATISTICS64
const struct vm_statistics64* vm = &dhost->vm_stats;
Expand All @@ -419,6 +419,20 @@ void Platform_setMemoryValues(Meter* mtr) {
mtr->values[MEMORY_METER_BUFFERS] = (double)vm->purgeable_count * page_K;
mtr->values[MEMORY_METER_CACHE] = (double)vm->inactive_count * page_K;
// mtr->values[MEMORY_METER_AVAILABLE] = "available memory"

*totalUsed = mtr->values[MEMORY_METER_USED];
// *totalUsed += mtr->values[MEMORY_METER_SHARED];
#ifdef HAVE_STRUCT_VM_STATISTICS64
*totalUsed += mtr->values[MEMORY_METER_COMPRESSED];
#endif

if (mtr->mode == BAR_METERMODE || mtr->mode == GRAPH_METERMODE) {
Settings *settings = mtr->host->settings;
if (!settings->showCachedMemory) {
mtr->values[MEMORY_METER_BUFFERS] = 0;
mtr->values[MEMORY_METER_CACHE] = 0;
}
}
}

void Platform_setSwapValues(Meter* mtr) {
Expand Down
4 changes: 3 additions & 1 deletion darwin/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ in the source distribution for its full text.
#include "CPUMeter.h"
#include "DiskIOMeter.h"
#include "Hashtable.h"
#include "Macros.h"
#include "NetworkIOMeter.h"
#include "ProcessLocksScreen.h"
#include "SignalsPanel.h"
Expand Down Expand Up @@ -60,7 +61,8 @@ double Platform_setCPUValues(Meter* mtr, unsigned int cpu);

void Platform_setGPUValues(Meter* mtr, double* totalUsage, unsigned long long* totalGPUTimeDiff);

void Platform_setMemoryValues(Meter* mtr);
ATTR_NONNULL
void Platform_setMemoryValues(Meter* mtr, double* totalUsed);

void Platform_setSwapValues(Meter* mtr);

Expand Down
14 changes: 13 additions & 1 deletion dragonflybsd/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) {
return percent;
}

void Platform_setMemoryValues(Meter* this) {
void Platform_setMemoryValues(Meter* this, double* totalUsed) {
const Machine* host = this->host;

this->total = host->totalMem;
Expand All @@ -230,6 +230,18 @@ void Platform_setMemoryValues(Meter* this) {
this->values[MEMORY_METER_BUFFERS] = host->buffersMem;
this->values[MEMORY_METER_CACHE] = host->cachedMem;
// this->values[MEMORY_METER_AVAILABLE] = "available memory"

*totalUsed = this->values[MEMORY_METER_USED];
// *totalUsed += this->values[MEMORY_METER_SHARED];
// *totalUsed += this->values[MEMORY_METER_COMPRESSED];

if (this->mode == BAR_METERMODE || this->mode == GRAPH_METERMODE) {
Settings *settings = host->settings;
if (!settings->showCachedMemory) {
this->values[MEMORY_METER_BUFFERS] = 0;
this->values[MEMORY_METER_CACHE] = 0;
}
}
}

void Platform_setSwapValues(Meter* this) {
Expand Down
3 changes: 2 additions & 1 deletion dragonflybsd/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ pid_t Platform_getMaxPid(void);

double Platform_setCPUValues(Meter* this, unsigned int cpu);

void Platform_setMemoryValues(Meter* this);
ATTR_NONNULL
void Platform_setMemoryValues(Meter* this, double* totalUsed);

void Platform_setSwapValues(Meter* this);

Expand Down
74 changes: 36 additions & 38 deletions freebsd/FreeBSDMachine.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,8 @@ static int MIB_vm_stats_vm_v_page_count[4];

static int MIB_vm_stats_vm_v_wire_count[4];
static int MIB_vm_stats_vm_v_active_count[4];
static int MIB_vm_stats_vm_v_cache_count[4];
static int MIB_vm_stats_vm_v_laundry_count[4];
static int MIB_vm_stats_vm_v_inactive_count[4];
static int MIB_vm_stats_vm_v_free_count[4];
static int MIB_vm_vmtotal[2];

static int MIB_vfs_bufspace[2];

Expand Down Expand Up @@ -77,10 +75,8 @@ Machine* Machine_new(UsersTable* usersTable, uid_t userId) {

len = 4; sysctlnametomib("vm.stats.vm.v_wire_count", MIB_vm_stats_vm_v_wire_count, &len);
len = 4; sysctlnametomib("vm.stats.vm.v_active_count", MIB_vm_stats_vm_v_active_count, &len);
len = 4; sysctlnametomib("vm.stats.vm.v_cache_count", MIB_vm_stats_vm_v_cache_count, &len);
len = 4; sysctlnametomib("vm.stats.vm.v_laundry_count", MIB_vm_stats_vm_v_laundry_count, &len);
len = 4; sysctlnametomib("vm.stats.vm.v_inactive_count", MIB_vm_stats_vm_v_inactive_count, &len);
len = 4; sysctlnametomib("vm.stats.vm.v_free_count", MIB_vm_stats_vm_v_free_count, &len);
len = 2; sysctlnametomib("vm.vmtotal", MIB_vm_vmtotal, &len);

len = 2; sysctlnametomib("vfs.bufspace", MIB_vfs_bufspace, &len);

Expand Down Expand Up @@ -310,65 +306,67 @@ static inline void FreeBSDMachine_scanCPU(Machine* super) {
static void FreeBSDMachine_scanMemoryInfo(Machine* super) {
FreeBSDMachine* this = (FreeBSDMachine*) super;

// @etosan:
// memory counter relationships seem to be these:
// total = active + wired + inactive + cache + free
// htop_used (unavail to anybody) = active + wired + inactive - buffer
// htop_cache (for cache meter) = buffer + cache
// htop_user_free (avail to procs) = buffer + cache + free
// htop_buffers (disk write buffer) = 0 (not applicable to FreeBSD)
// comment by Pierre-Marie Baty <[email protected]>
//
// 'buffer' contain cache used by most file systems other than ZFS, and is
// included in 'wired'
// FreeBSD has the following memory classes:
// active: userland pages currently mapped to physical memory (i.e. in use)
// inactive: userland pages that are no longer active, can be (re)allocated to processes
// laundry: userland pages that were just released, now being flushed, will become inactive
// wired: kernel pages currently mapped to physical memory, cannot be paged out nor swapped
// buffers: subcategory of 'wired' corresponding to the filesystem caches
// free: pages that haven't been allocated yet, or have been released
//
// with ZFS ARC situation becomes bit muddled, as ARC behaves like "user_free"
// and belongs into cache, but is reported as wired by kernel
// htop has the following memory classes:
// super->usedMem: can be mapped to FreeBSD's ('wired' - 'buffers') + 'laundry' + 'active'
// super->buffersMem: can be mapped to FreeBSD's 'buffers'
// super->cachedMem: can be mapped to FreeBSD's 'inactive'. Inactive pages are cached allocations.
//
// htop_used = active + (wired - arc)
// htop_cache = buffers + cache + arc
// With ZFS, the ARC area is NOT counted in the 'buffers' class, but is still counted in the 'wired'
// class. The ARC total must thus be substracted from the 'wired' class AND added to the 'buffer' class,
// so that the result (ARC being shown in buffersMem) is consistent with what ZFS users would expect.
// This adjustment is done in Platform_setMemoryValues() in freebsd/Platform.c.

u_long totalMem;
u_int memActive, memWire, memInactive, cachedMem;
u_int memActive, memWire, memInactive, memLaundry;
long buffersMem;
size_t len;
struct vmtotal vmtotal;

//disabled for now, as it is always smaller than phycal amount of memory...
//...to avoid "where is my memory?" questions
//sysctl(MIB_vm_stats_vm_v_page_count, 4, &(super->totalMem), &len, NULL, 0);
//super->totalMem *= this->pageSizeKb;
// total memory
len = sizeof(totalMem);
sysctl(MIB_hw_physmem, 2, &(totalMem), &len, NULL, 0);
totalMem /= 1024;
super->totalMem = totalMem;
super->totalMem = totalMem / 1024;

// 'active' pages
len = sizeof(memActive);
sysctl(MIB_vm_stats_vm_v_active_count, 4, &(memActive), &len, NULL, 0);
memActive *= this->pageSizeKb;

// 'wired' pages
len = sizeof(memWire);
sysctl(MIB_vm_stats_vm_v_wire_count, 4, &(memWire), &len, NULL, 0);
memWire *= this->pageSizeKb;

// 'inactive' pages
len = sizeof(memInactive);
sysctl(MIB_vm_stats_vm_v_inactive_count, 4, &(memInactive), &len, NULL, 0);
memInactive *= this->pageSizeKb;

// 'laundry' pages
len = sizeof(memLaundry);
sysctl(MIB_vm_stats_vm_v_laundry_count, 4, &(memLaundry), &len, NULL, 0);
memLaundry *= this->pageSizeKb;

// 'buffers' pages (separate read, should be deducted from 'wired')
len = sizeof(buffersMem);
sysctl(MIB_vfs_bufspace, 2, &(buffersMem), &len, NULL, 0);
buffersMem /= 1024;
super->cachedMem = buffersMem;

len = sizeof(cachedMem);
sysctl(MIB_vm_stats_vm_v_cache_count, 4, &(cachedMem), &len, NULL, 0);
cachedMem *= this->pageSizeKb;
super->cachedMem += cachedMem;

len = sizeof(vmtotal);
sysctl(MIB_vm_vmtotal, 2, &(vmtotal), &len, NULL, 0);
super->sharedMem = vmtotal.t_rmshr * this->pageSizeKb;

super->usedMem = memActive + memWire + memInactive - buffersMem;
// now fill in the htop categories
super->usedMem = (memWire - buffersMem) + memLaundry + memActive;
super->cachedMem = memInactive;
super->buffersMem = buffersMem;

// swap
struct kvm_swap swap[16];
int nswap = kvm_getswapinfo(this->kd, swap, ARRAYSIZE(swap), 0);
super->totalSwap = 0;
Expand Down
21 changes: 19 additions & 2 deletions freebsd/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu) {
return percent;
}

void Platform_setMemoryValues(Meter* this) {
void Platform_setMemoryValues(Meter* this, double* totalUsed) {
const Machine* host = this->host;
const FreeBSDMachine* fhost = (const FreeBSDMachine*) host;

Expand All @@ -243,9 +243,26 @@ void Platform_setMemoryValues(Meter* this) {
if (fhost->zfs.size > fhost->zfs.min)
shrinkableSize = fhost->zfs.size - fhost->zfs.min;
this->values[MEMORY_METER_USED] -= shrinkableSize;
this->values[MEMORY_METER_CACHE] += shrinkableSize;
this->values[MEMORY_METER_BUFFERS] += shrinkableSize;
// this->values[MEMORY_METER_AVAILABLE] += shrinkableSize;
}

*totalUsed = this->values[MEMORY_METER_USED];
*totalUsed += this->values[MEMORY_METER_SHARED];
// *totalUsed += this->values[MEMORY_METER_COMPRESSED];
// In FreeBSD, 'buffers' memory is a subcategory of 'wired' and is
// not reclaimable. It can be considered as 'used' as well.
*totalUsed += this->values[MEMORY_METER_BUFFERS];

Settings *settings = host->settings;
if (!settings->showCachedMemory) {
this->values[MEMORY_METER_USED] += this->values[MEMORY_METER_BUFFERS];
this->values[MEMORY_METER_BUFFERS] = NAN;

if (this->mode == BAR_METERMODE || this->mode == GRAPH_METERMODE) {
this->values[MEMORY_METER_CACHE] = 0;
}
}
}

void Platform_setSwapValues(Meter* this) {
Expand Down
4 changes: 3 additions & 1 deletion freebsd/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ in the source distribution for its full text.
#include "BatteryMeter.h"
#include "DiskIOMeter.h"
#include "Hashtable.h"
#include "Macros.h"
#include "Meter.h"
#include "NetworkIOMeter.h"
#include "Process.h"
Expand Down Expand Up @@ -49,7 +50,8 @@ pid_t Platform_getMaxPid(void);

double Platform_setCPUValues(Meter* this, unsigned int cpu);

void Platform_setMemoryValues(Meter* this);
ATTR_NONNULL
void Platform_setMemoryValues(Meter* this, double* totalUsed);

void Platform_setSwapValues(Meter* this);

Expand Down
17 changes: 16 additions & 1 deletion linux/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -417,7 +417,7 @@ void Platform_setGPUValues(Meter* this, double* totalUsage, unsigned long long*
this->values[residueIndex] = residuePercentage;
}

void Platform_setMemoryValues(Meter* this) {
void Platform_setMemoryValues(Meter* this, double* totalUsed) {
const Machine* host = this->host;
const LinuxMachine* lhost = (const LinuxMachine*) host;

Expand All @@ -443,6 +443,21 @@ void Platform_setMemoryValues(Meter* this) {
this->values[MEMORY_METER_USED] -= lhost->zswap.usedZswapComp;
this->values[MEMORY_METER_COMPRESSED] += lhost->zswap.usedZswapComp;
}

*totalUsed = this->values[MEMORY_METER_USED];
*totalUsed += this->values[MEMORY_METER_SHARED];
*totalUsed += this->values[MEMORY_METER_COMPRESSED];

if (this->mode == BAR_METERMODE || this->mode == GRAPH_METERMODE) {
Settings *settings = host->settings;
if (!settings->showCachedMemory) {
this->values[MEMORY_METER_BUFFERS] = 0;
this->values[MEMORY_METER_CACHE] = 0;
}

// 'available' memory is never drawn
this->values[MEMORY_METER_AVAILABLE] = 0;
}
}

void Platform_setSwapValues(Meter* this) {
Expand Down
3 changes: 2 additions & 1 deletion linux/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,8 @@ double Platform_setCPUValues(Meter* this, unsigned int cpu);

void Platform_setGPUValues(Meter* this, double* totalUsage, unsigned long long* totalGPUTimeDiff);

void Platform_setMemoryValues(Meter* this);
ATTR_NONNULL
void Platform_setMemoryValues(Meter* this, double* totalUsed);

void Platform_setSwapValues(Meter* this);

Expand Down
14 changes: 13 additions & 1 deletion netbsd/Platform.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ double Platform_setCPUValues(Meter* this, int cpu) {
return totalPercent;
}

void Platform_setMemoryValues(Meter* this) {
void Platform_setMemoryValues(Meter* this, double* totalUsed) {
const Machine* host = this->host;
this->total = host->totalMem;
this->values[MEMORY_METER_USED] = host->usedMem;
Expand All @@ -281,6 +281,18 @@ void Platform_setMemoryValues(Meter* this) {
this->values[MEMORY_METER_BUFFERS] = host->buffersMem;
this->values[MEMORY_METER_CACHE] = host->cachedMem;
// this->values[MEMORY_METER_AVAILABLE] = "available memory"

*totalUsed = this->values[MEMORY_METER_USED];
// *totalUsed += this->values[MEMORY_METER_SHARED];
// *totalUsed += this->values[MEMORY_METER_COMPRESSED];

if (this->mode == BAR_METERMODE || this->mode == GRAPH_METERMODE) {
Settings *settings = host->settings;
if (!settings->showCachedMemory) {
this->values[MEMORY_METER_BUFFERS] = 0;
this->values[MEMORY_METER_CACHE] = 0;
}
}
}

void Platform_setSwapValues(Meter* this) {
Expand Down
Loading
Loading