summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClement Tsang <34804052+ClementTsang@users.noreply.github.com>2021-07-17 22:27:40 -0400
committerGitHub <noreply@github.com>2021-07-17 22:27:40 -0400
commit2736dc9b35739b9b48d8ac2ad0b5d3671813c725 (patch)
tree9bbe4f73db7a6e16e04ee430d6d82235c47debb4
parent7f24e6286735abcee6c3137dd9c22a7a178740a3 (diff)
refactor: switch to manual implementation of meminfo parse (#548)
Manually parse `/proc/meminfo` for the purposes of memory usage.
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml3
-rw-r--r--docs/content/usage/widgets/memory.md2
-rw-r--r--src/app/data_harvester/memory/general.rs52
4 files changed, 50 insertions, 8 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 8b38605d..d4b77036 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -258,6 +258,7 @@ dependencies = [
"procfs",
"regex",
"serde",
+ "smol",
"sysinfo",
"thiserror",
"toml",
diff --git a/Cargo.toml b/Cargo.toml
index c104daa2..e7bdfe3b 100644
--- a/Cargo.toml
+++ b/Cargo.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"] }
diff --git a/docs/content/usage/widgets/memory.md b/docs/content/usage/widgets/memory.md
index f25dbe36..59d36c9a 100644
--- a/docs/content/usage/widgets/memory.md
+++ b/docs/content/usage/widgets/memory.md
@@ -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.
diff --git a/src/app/data_harvester/memory/general.rs b/src/app/data_harvester/memory/general.rs
index 4af287d7..2afe119f 100644
--- a/src/app/data_harvester/memory/general.rs
+++ b/src/app/data_harvester/memory/general.rs
@@ -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)