mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-04-08 17:05:59 +02:00
refactor: switch to manual implementation of meminfo parse (#548)
Manually parse `/proc/meminfo` for the purposes of memory usage.
This commit is contained in:
parent
7f24e62867
commit
2736dc9b35
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -258,6 +258,7 @@ dependencies = [
|
||||
"procfs",
|
||||
"regex",
|
||||
"serde",
|
||||
"smol",
|
||||
"sysinfo",
|
||||
"thiserror",
|
||||
"toml",
|
||||
|
@ -68,8 +68,9 @@ log = { version = "0.4.14", optional = true }
|
||||
libc = "0.2.86"
|
||||
|
||||
[target.'cfg(target_os = "linux")'.dependencies]
|
||||
heim = { version = "0.1.0-rc.1", features = ["cpu", "disk", "memory", "net", "sensors"] }
|
||||
heim = { version = "0.1.0-rc.1", features = ["cpu", "disk", "net", "sensors"] }
|
||||
procfs = "0.9.1"
|
||||
smol = "1.2.5"
|
||||
|
||||
[target.'cfg(target_os = "macos")'.dependencies]
|
||||
heim = { version = "0.1.0-rc.1", features = ["cpu", "disk", "memory", "net"] }
|
||||
|
@ -8,7 +8,7 @@ The memory widget provides a visual representation of RAM and swap usage over ti
|
||||
|
||||
## Features
|
||||
|
||||
The legend displays the current usage in terms of percentage and actual usage.
|
||||
The legend displays the current usage in terms of percentage and actual usage in binary units (KiB, MiB, GiB, etc.).
|
||||
If the total RAM or swap available is 0, then it is automatically hidden from the legend and graph.
|
||||
|
||||
One can also adjust the displayed time range through either the keyboard or mouse, with a range of 30s to 600s.
|
||||
|
@ -26,7 +26,48 @@ pub async fn get_ram_data() -> crate::utils::error::Result<Option<MemHarvest>> {
|
||||
let (mem_total_in_kib, mem_used_in_kib) = {
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let mem_info = procfs::Meminfo::new()?;
|
||||
use smol::fs::read_to_string;
|
||||
let meminfo = read_to_string("/proc/meminfo").await?;
|
||||
|
||||
// All values are in KiB by default.
|
||||
let mut mem_total = 0;
|
||||
let mut cached = 0;
|
||||
let mut s_reclaimable = 0;
|
||||
let mut shmem = 0;
|
||||
let mut buffers = 0;
|
||||
let mut mem_free = 0;
|
||||
|
||||
let mut keys_read: u8 = 0;
|
||||
const TOTAL_KEYS_NEEDED: u8 = 6;
|
||||
|
||||
for line in meminfo.lines() {
|
||||
if let Some((label, value)) = line.split_once(':') {
|
||||
let to_write = match label {
|
||||
"MemTotal" => &mut mem_total,
|
||||
"MemFree" => &mut mem_free,
|
||||
"Buffers" => &mut buffers,
|
||||
"Cached" => &mut cached,
|
||||
"Shmem" => &mut shmem,
|
||||
"SReclaimable" => &mut s_reclaimable,
|
||||
_ => {
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
if let Some((number, _unit)) = value.trim_start().split_once(' ') {
|
||||
// Parse the value, remember it's in KiB!
|
||||
if let Ok(number) = number.parse::<u64>() {
|
||||
*to_write = number;
|
||||
|
||||
// We only need a few keys, so we can bail early.
|
||||
keys_read += 1;
|
||||
if keys_read == TOTAL_KEYS_NEEDED {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Let's preface this by saying that memory usage calculations are... not straightforward.
|
||||
// There are conflicting implementations everywhere.
|
||||
@ -39,14 +80,13 @@ pub async fn get_ram_data() -> crate::utils::error::Result<Option<MemHarvest>> {
|
||||
// Another implementation, commonly used in other things, is to skip the shmem part of the calculation,
|
||||
// which matches gopsutil and stuff like free.
|
||||
|
||||
let total = mem_info.mem_total / 1024;
|
||||
let cached_mem =
|
||||
mem_info.cached + mem_info.s_reclaimable.unwrap_or(0) - mem_info.shmem.unwrap_or(0);
|
||||
let used_diff = (mem_info.mem_free + cached_mem + mem_info.buffers) / 1024;
|
||||
let total = mem_total;
|
||||
let cached_mem = cached + s_reclaimable - shmem;
|
||||
let used_diff = mem_free + cached_mem + buffers;
|
||||
let used = if total >= used_diff {
|
||||
total - used_diff
|
||||
} else {
|
||||
total - mem_info.mem_free
|
||||
total - mem_free
|
||||
};
|
||||
|
||||
(total, used)
|
||||
|
Loading…
x
Reference in New Issue
Block a user