refactor: use nonzero in mem data (#1673)
* refactor: use nonzerou64 for mem data * clippy * comment
This commit is contained in:
parent
22fbd7d630
commit
702775f58d
|
@ -7,7 +7,7 @@ use std::{
|
||||||
use crate::collection::batteries;
|
use crate::collection::batteries;
|
||||||
use crate::{
|
use crate::{
|
||||||
app::AppConfigFields,
|
app::AppConfigFields,
|
||||||
collection::{cpu, disks, memory::MemHarvest, network, Data},
|
collection::{cpu, disks, memory::MemData, network, Data},
|
||||||
dec_bytes_per_second_string,
|
dec_bytes_per_second_string,
|
||||||
utils::data_units::DataUnit,
|
utils::data_units::DataUnit,
|
||||||
widgets::{DiskWidgetData, TempWidgetData},
|
widgets::{DiskWidgetData, TempWidgetData},
|
||||||
|
@ -23,14 +23,14 @@ pub struct StoredData {
|
||||||
pub last_update_time: Instant, // FIXME: (points_rework_v1) remove this?
|
pub last_update_time: Instant, // FIXME: (points_rework_v1) remove this?
|
||||||
pub timeseries_data: TimeSeriesData, // FIXME: (points_rework_v1) Skip in basic?
|
pub timeseries_data: TimeSeriesData, // FIXME: (points_rework_v1) Skip in basic?
|
||||||
pub network_harvest: network::NetworkHarvest,
|
pub network_harvest: network::NetworkHarvest,
|
||||||
pub ram_harvest: MemHarvest,
|
pub ram_harvest: Option<MemData>,
|
||||||
pub swap_harvest: Option<MemHarvest>,
|
pub swap_harvest: Option<MemData>,
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
pub cache_harvest: Option<MemHarvest>,
|
pub cache_harvest: Option<MemData>,
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
pub arc_harvest: Option<MemHarvest>,
|
pub arc_harvest: Option<MemData>,
|
||||||
#[cfg(feature = "gpu")]
|
#[cfg(feature = "gpu")]
|
||||||
pub gpu_harvest: Vec<(String, MemHarvest)>,
|
pub gpu_harvest: Vec<(String, MemData)>,
|
||||||
pub cpu_harvest: cpu::CpuHarvest,
|
pub cpu_harvest: cpu::CpuHarvest,
|
||||||
pub load_avg_harvest: cpu::LoadAvgHarvest,
|
pub load_avg_harvest: cpu::LoadAvgHarvest,
|
||||||
pub process_data: ProcessData,
|
pub process_data: ProcessData,
|
||||||
|
@ -48,7 +48,7 @@ impl Default for StoredData {
|
||||||
last_update_time: Instant::now(),
|
last_update_time: Instant::now(),
|
||||||
timeseries_data: TimeSeriesData::default(),
|
timeseries_data: TimeSeriesData::default(),
|
||||||
network_harvest: network::NetworkHarvest::default(),
|
network_harvest: network::NetworkHarvest::default(),
|
||||||
ram_harvest: MemHarvest::default(),
|
ram_harvest: None,
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
cache_harvest: None,
|
cache_harvest: None,
|
||||||
swap_harvest: None,
|
swap_harvest: None,
|
||||||
|
@ -96,10 +96,7 @@ impl StoredData {
|
||||||
self.network_harvest = network;
|
self.network_harvest = network;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(memory) = data.memory {
|
self.ram_harvest = data.memory;
|
||||||
self.ram_harvest = memory;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.swap_harvest = data.swap;
|
self.swap_harvest = data.swap;
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
|
|
|
@ -99,13 +99,13 @@ impl TimeSeriesData {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(memory) = &data.memory {
|
if let Some(memory) = &data.memory {
|
||||||
self.ram.try_push(memory.checked_percent());
|
self.ram.push(memory.percentage());
|
||||||
} else {
|
} else {
|
||||||
self.ram.insert_break();
|
self.ram.insert_break();
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(swap) = &data.swap {
|
if let Some(swap) = &data.swap {
|
||||||
self.swap.try_push(swap.checked_percent());
|
self.swap.push(swap.percentage());
|
||||||
} else {
|
} else {
|
||||||
self.swap.insert_break();
|
self.swap.insert_break();
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,7 @@ impl TimeSeriesData {
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
{
|
{
|
||||||
if let Some(cache) = &data.cache {
|
if let Some(cache) = &data.cache {
|
||||||
self.cache_mem.try_push(cache.checked_percent());
|
self.cache_mem.push(cache.percentage());
|
||||||
} else {
|
} else {
|
||||||
self.cache_mem.insert_break();
|
self.cache_mem.insert_break();
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ impl TimeSeriesData {
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
{
|
{
|
||||||
if let Some(arc) = &data.arc {
|
if let Some(arc) = &data.arc {
|
||||||
self.arc_mem.try_push(arc.checked_percent());
|
self.arc_mem.push(arc.percentage());
|
||||||
} else {
|
} else {
|
||||||
self.arc_mem.insert_break();
|
self.arc_mem.insert_break();
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ impl TimeSeriesData {
|
||||||
.gpu_mem
|
.gpu_mem
|
||||||
.get_mut(name)
|
.get_mut(name)
|
||||||
.expect("entry must exist as it was created above");
|
.expect("entry must exist as it was created above");
|
||||||
curr.try_push(new_data.checked_percent());
|
curr.push(new_data.percentage());
|
||||||
}
|
}
|
||||||
|
|
||||||
for nv in not_visited {
|
for nv in not_visited {
|
||||||
|
|
|
@ -8,37 +8,31 @@ use tui::{
|
||||||
use crate::{
|
use crate::{
|
||||||
app::App,
|
app::App,
|
||||||
canvas::{components::pipe_gauge::PipeGauge, drawing_utils::widget_block, Painter},
|
canvas::{components::pipe_gauge::PipeGauge, drawing_utils::widget_block, Painter},
|
||||||
collection::memory::MemHarvest,
|
collection::memory::MemData,
|
||||||
get_binary_unit_and_denominator,
|
get_binary_unit_and_denominator,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Convert memory info into a string representing a fraction.
|
/// Convert memory info into a string representing a fraction.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn memory_fraction_label(data: &MemHarvest) -> Cow<'static, str> {
|
fn memory_fraction_label(data: &MemData) -> Cow<'static, str> {
|
||||||
if data.total_bytes > 0 {
|
let total_bytes = data.total_bytes.get();
|
||||||
let (unit, denominator) = get_binary_unit_and_denominator(data.total_bytes);
|
let (unit, denominator) = get_binary_unit_and_denominator(total_bytes);
|
||||||
let used = data.used_bytes as f64 / denominator;
|
let used = data.used_bytes as f64 / denominator;
|
||||||
let total = data.total_bytes as f64 / denominator;
|
let total = total_bytes as f64 / denominator;
|
||||||
|
|
||||||
format!("{used:.1}{unit}/{total:.1}{unit}").into()
|
format!("{used:.1}{unit}/{total:.1}{unit}").into()
|
||||||
} else {
|
|
||||||
"0.0B/0.0B".into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Convert memory info into a string representing a percentage.
|
/// Convert memory info into a string representing a percentage.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn memory_percentage_label(data: &MemHarvest) -> Cow<'static, str> {
|
fn memory_percentage_label(data: &MemData) -> Cow<'static, str> {
|
||||||
if data.total_bytes > 0 {
|
let total_bytes = data.total_bytes.get();
|
||||||
let percentage = data.used_bytes as f64 / data.total_bytes as f64 * 100.0;
|
let percentage = data.used_bytes as f64 / total_bytes as f64 * 100.0;
|
||||||
format!("{percentage:3.0}%").into()
|
format!("{percentage:3.0}%").into()
|
||||||
} else {
|
|
||||||
" 0%".into()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn memory_label(data: &MemHarvest, is_percentage: bool) -> Cow<'static, str> {
|
fn memory_label(data: &MemData, is_percentage: bool) -> Cow<'static, str> {
|
||||||
if is_percentage {
|
if is_percentage {
|
||||||
memory_percentage_label(data)
|
memory_percentage_label(data)
|
||||||
} else {
|
} else {
|
||||||
|
@ -62,8 +56,21 @@ impl Painter {
|
||||||
|
|
||||||
let data = app_state.data_store.get_data();
|
let data = app_state.data_store.get_data();
|
||||||
|
|
||||||
let ram_percentage = data.ram_harvest.saturating_percentage();
|
let (ram_percentage, ram_label) = if let Some(ram_harvest) = &data.ram_harvest {
|
||||||
let ram_label = memory_label(&data.ram_harvest, app_state.basic_mode_use_percent);
|
(
|
||||||
|
ram_harvest.percentage(),
|
||||||
|
memory_label(ram_harvest, app_state.basic_mode_use_percent),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
(
|
||||||
|
0.0,
|
||||||
|
if app_state.basic_mode_use_percent {
|
||||||
|
"0.0B/0.0B".into()
|
||||||
|
} else {
|
||||||
|
" 0%".into()
|
||||||
|
},
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
draw_widgets.push(
|
draw_widgets.push(
|
||||||
PipeGauge::default()
|
PipeGauge::default()
|
||||||
|
@ -75,7 +82,7 @@ impl Painter {
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(swap_harvest) = &data.swap_harvest {
|
if let Some(swap_harvest) = &data.swap_harvest {
|
||||||
let swap_percentage = swap_harvest.saturating_percentage();
|
let swap_percentage = swap_harvest.percentage();
|
||||||
let swap_label = memory_label(swap_harvest, app_state.basic_mode_use_percent);
|
let swap_label = memory_label(swap_harvest, app_state.basic_mode_use_percent);
|
||||||
|
|
||||||
draw_widgets.push(
|
draw_widgets.push(
|
||||||
|
@ -91,7 +98,7 @@ impl Painter {
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
{
|
{
|
||||||
if let Some(cache_harvest) = &data.cache_harvest {
|
if let Some(cache_harvest) = &data.cache_harvest {
|
||||||
let cache_percentage = cache_harvest.saturating_percentage();
|
let cache_percentage = cache_harvest.percentage();
|
||||||
let cache_fraction_label =
|
let cache_fraction_label =
|
||||||
memory_label(cache_harvest, app_state.basic_mode_use_percent);
|
memory_label(cache_harvest, app_state.basic_mode_use_percent);
|
||||||
|
|
||||||
|
@ -109,7 +116,7 @@ impl Painter {
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
{
|
{
|
||||||
if let Some(arc_harvest) = &data.arc_harvest {
|
if let Some(arc_harvest) = &data.arc_harvest {
|
||||||
let arc_percentage = arc_harvest.saturating_percentage();
|
let arc_percentage = arc_harvest.percentage();
|
||||||
let arc_fraction_label =
|
let arc_fraction_label =
|
||||||
memory_label(arc_harvest, app_state.basic_mode_use_percent);
|
memory_label(arc_harvest, app_state.basic_mode_use_percent);
|
||||||
|
|
||||||
|
@ -130,7 +137,7 @@ impl Painter {
|
||||||
let mut colour_index = 0;
|
let mut colour_index = 0;
|
||||||
|
|
||||||
for (_, harvest) in data.gpu_harvest.iter() {
|
for (_, harvest) in data.gpu_harvest.iter() {
|
||||||
let percentage = harvest.saturating_percentage();
|
let percentage = harvest.percentage();
|
||||||
let label = memory_label(harvest, app_state.basic_mode_use_percent);
|
let label = memory_label(harvest, app_state.basic_mode_use_percent);
|
||||||
|
|
||||||
let style = {
|
let style = {
|
||||||
|
|
|
@ -14,24 +14,21 @@ use crate::{
|
||||||
drawing_utils::should_hide_x_label,
|
drawing_utils::should_hide_x_label,
|
||||||
Painter,
|
Painter,
|
||||||
},
|
},
|
||||||
collection::memory::MemHarvest,
|
collection::memory::MemData,
|
||||||
get_binary_unit_and_denominator,
|
get_binary_unit_and_denominator,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Convert memory info into a combined memory label.
|
/// Convert memory info into a combined memory label.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn memory_legend_label(name: &str, data: Option<&MemHarvest>) -> String {
|
fn memory_legend_label(name: &str, data: Option<&MemData>) -> String {
|
||||||
if let Some(data) = data {
|
if let Some(data) = data {
|
||||||
if data.total_bytes > 0 {
|
let total_bytes = data.total_bytes.get();
|
||||||
let percentage = data.used_bytes as f64 / data.total_bytes as f64 * 100.0;
|
let percentage = data.used_bytes as f64 / total_bytes as f64 * 100.0;
|
||||||
let (unit, denominator) = get_binary_unit_and_denominator(data.total_bytes);
|
let (unit, denominator) = get_binary_unit_and_denominator(total_bytes);
|
||||||
let used = data.used_bytes as f64 / denominator;
|
let used = data.used_bytes as f64 / denominator;
|
||||||
let total = data.total_bytes as f64 / denominator;
|
let total = total_bytes as f64 / denominator;
|
||||||
|
|
||||||
format!("{name}:{percentage:3.0}% {used:.1}{unit}/{total:.1}{unit}")
|
format!("{name}:{percentage:3.0}% {used:.1}{unit}/{total:.1}{unit}")
|
||||||
} else {
|
|
||||||
format!("{name}: 0% 0.0B/0.0B")
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
format!("{name}: 0% 0.0B/0.0B")
|
format!("{name}: 0% 0.0B/0.0B")
|
||||||
}
|
}
|
||||||
|
@ -40,7 +37,7 @@ fn memory_legend_label(name: &str, data: Option<&MemHarvest>) -> String {
|
||||||
/// Get graph data.
|
/// Get graph data.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn graph_data<'a>(
|
fn graph_data<'a>(
|
||||||
out: &mut Vec<GraphData<'a>>, name: &str, last_harvest: Option<&'a MemHarvest>,
|
out: &mut Vec<GraphData<'a>>, name: &str, last_harvest: Option<&'a MemData>,
|
||||||
time: &'a [Instant], values: &'a Values, style: Style,
|
time: &'a [Instant], values: &'a Values, style: Style,
|
||||||
) {
|
) {
|
||||||
if !values.no_elements() {
|
if !values.no_elements() {
|
||||||
|
@ -97,10 +94,11 @@ impl Painter {
|
||||||
let timeseries = &data.timeseries_data;
|
let timeseries = &data.timeseries_data;
|
||||||
let time = ×eries.time;
|
let time = ×eries.time;
|
||||||
|
|
||||||
|
// TODO: Add a "no data" option here/to time graph if there is no entries
|
||||||
graph_data(
|
graph_data(
|
||||||
&mut points,
|
&mut points,
|
||||||
"RAM",
|
"RAM",
|
||||||
Some(&data.ram_harvest),
|
data.ram_harvest.as_ref(),
|
||||||
time,
|
time,
|
||||||
×eries.ram,
|
×eries.ram,
|
||||||
self.styles.ram_style,
|
self.styles.ram_style,
|
||||||
|
|
|
@ -36,10 +36,10 @@ pub struct Data {
|
||||||
pub collection_time: Instant,
|
pub collection_time: Instant,
|
||||||
pub cpu: Option<cpu::CpuHarvest>,
|
pub cpu: Option<cpu::CpuHarvest>,
|
||||||
pub load_avg: Option<cpu::LoadAvgHarvest>,
|
pub load_avg: Option<cpu::LoadAvgHarvest>,
|
||||||
pub memory: Option<memory::MemHarvest>,
|
pub memory: Option<memory::MemData>,
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
pub cache: Option<memory::MemHarvest>,
|
pub cache: Option<memory::MemData>,
|
||||||
pub swap: Option<memory::MemHarvest>,
|
pub swap: Option<memory::MemData>,
|
||||||
pub temperature_sensors: Option<Vec<temperature::TempSensorData>>,
|
pub temperature_sensors: Option<Vec<temperature::TempSensorData>>,
|
||||||
pub network: Option<network::NetworkHarvest>,
|
pub network: Option<network::NetworkHarvest>,
|
||||||
pub list_of_processes: Option<Vec<processes::ProcessHarvest>>,
|
pub list_of_processes: Option<Vec<processes::ProcessHarvest>>,
|
||||||
|
@ -48,9 +48,9 @@ pub struct Data {
|
||||||
#[cfg(feature = "battery")]
|
#[cfg(feature = "battery")]
|
||||||
pub list_of_batteries: Option<Vec<batteries::BatteryData>>,
|
pub list_of_batteries: Option<Vec<batteries::BatteryData>>,
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
pub arc: Option<memory::MemHarvest>,
|
pub arc: Option<memory::MemData>,
|
||||||
#[cfg(feature = "gpu")]
|
#[cfg(feature = "gpu")]
|
||||||
pub gpu: Option<Vec<(String, memory::MemHarvest)>>,
|
pub gpu: Option<Vec<(String, memory::MemData)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Data {
|
impl Default for Data {
|
||||||
|
@ -345,7 +345,7 @@ impl DataCollector {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn update_gpus(&mut self) {
|
fn update_gpus(&mut self) {
|
||||||
if self.widgets_to_harvest.use_gpu {
|
if self.widgets_to_harvest.use_gpu {
|
||||||
let mut local_gpu: Vec<(String, memory::MemHarvest)> = Vec::new();
|
let mut local_gpu: Vec<(String, memory::MemData)> = Vec::new();
|
||||||
let mut local_gpu_pids: Vec<HashMap<u32, (u64, u32)>> = Vec::new();
|
let mut local_gpu_pids: Vec<HashMap<u32, (u64, u32)>> = Vec::new();
|
||||||
let mut local_gpu_total_mem: u64 = 0;
|
let mut local_gpu_total_mem: u64 = 0;
|
||||||
|
|
||||||
|
@ -501,7 +501,7 @@ impl DataCollector {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn total_memory(&self) -> u64 {
|
fn total_memory(&self) -> u64 {
|
||||||
if let Some(memory) = &self.data.memory {
|
if let Some(memory) = &self.data.memory {
|
||||||
memory.total_bytes
|
memory.total_bytes.get()
|
||||||
} else {
|
} else {
|
||||||
self.sys.system.total_memory()
|
self.sys.system.total_memory()
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,20 @@ mod amdgpu_marketing;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{filter::Filter, layout_manager::UsedWidgets},
|
app::{filter::Filter, layout_manager::UsedWidgets},
|
||||||
collection::{memory::MemHarvest, temperature::TempSensorData},
|
collection::{memory::MemData, temperature::TempSensorData},
|
||||||
};
|
};
|
||||||
use hashbrown::{HashMap, HashSet};
|
use hashbrown::{HashMap, HashSet};
|
||||||
use std::{
|
use std::{
|
||||||
fs,
|
fs::{self, read_to_string},
|
||||||
fs::read_to_string,
|
num::NonZeroU64,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::{LazyLock, Mutex},
|
sync::{LazyLock, Mutex},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: May be able to clean up some of these, Option<Vec> for example is a bit redundant.
|
||||||
pub struct AMDGPUData {
|
pub struct AMDGPUData {
|
||||||
pub memory: Option<Vec<(String, MemHarvest)>>,
|
pub memory: Option<Vec<(String, MemData)>>,
|
||||||
pub temperature: Option<Vec<TempSensorData>>,
|
pub temperature: Option<Vec<TempSensorData>>,
|
||||||
pub procs: Option<(u64, Vec<HashMap<u32, (u64, u32)>>)>,
|
pub procs: Option<(u64, Vec<HashMap<u32, (u64, u32)>>)>,
|
||||||
}
|
}
|
||||||
|
@ -415,13 +416,15 @@ pub fn get_amd_vecs(
|
||||||
|
|
||||||
if let Some(mem) = get_amd_vram(&device_path) {
|
if let Some(mem) = get_amd_vram(&device_path) {
|
||||||
if widgets_to_harvest.use_mem {
|
if widgets_to_harvest.use_mem {
|
||||||
mem_vec.push((
|
if let Some(total_bytes) = NonZeroU64::new(mem.total) {
|
||||||
device_name.clone(),
|
mem_vec.push((
|
||||||
MemHarvest {
|
device_name.clone(),
|
||||||
total_bytes: mem.total,
|
MemData {
|
||||||
used_bytes: mem.used,
|
total_bytes,
|
||||||
},
|
used_bytes: mem.used,
|
||||||
));
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
total_mem += mem.total
|
total_mem += mem.total
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
//! Memory data collection.
|
//! Memory data collection.
|
||||||
|
|
||||||
|
use std::num::NonZeroU64;
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
pub(crate) use self::sysinfo::get_cache_usage;
|
pub(crate) use self::sysinfo::get_cache_usage;
|
||||||
pub(crate) use self::sysinfo::{get_ram_usage, get_swap_usage};
|
pub(crate) use self::sysinfo::{get_ram_usage, get_swap_usage};
|
||||||
|
|
||||||
pub mod sysinfo;
|
pub mod sysinfo;
|
||||||
|
|
||||||
// cfg_if::cfg_if! {
|
// cfg_if::cfg_if! {
|
||||||
// if #[cfg(target_os = "windows")] {
|
// if #[cfg(target_os = "windows")] {
|
||||||
// mod windows;
|
// mod windows;
|
||||||
|
@ -15,36 +18,19 @@ pub mod sysinfo;
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
pub mod arc;
|
pub mod arc;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Default)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct MemHarvest {
|
pub struct MemData {
|
||||||
pub used_bytes: u64,
|
pub used_bytes: u64,
|
||||||
pub total_bytes: u64,
|
pub total_bytes: NonZeroU64,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MemHarvest {
|
impl MemData {
|
||||||
/// Return the use percentage. If the total bytes is 0, then this returns `None`.
|
/// Return the use percentage.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn checked_percent(&self) -> Option<f64> {
|
pub fn percentage(&self) -> f64 {
|
||||||
let used = self.used_bytes as f64;
|
let used = self.used_bytes as f64;
|
||||||
let total = self.total_bytes as f64;
|
let total = self.total_bytes.get() as f64;
|
||||||
|
|
||||||
if total == 0.0 {
|
used / total * 100.0
|
||||||
None
|
|
||||||
} else {
|
|
||||||
Some(used / total * 100.0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Return the use percentage. If the total bytes is 0, then this returns 0.0.
|
|
||||||
#[inline]
|
|
||||||
pub fn saturating_percentage(&self) -> f64 {
|
|
||||||
let used = self.used_bytes as f64;
|
|
||||||
let total = self.total_bytes as f64;
|
|
||||||
|
|
||||||
if total == 0.0 {
|
|
||||||
0.0
|
|
||||||
} else {
|
|
||||||
used / total * 100.0
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
use super::MemHarvest;
|
use super::MemData;
|
||||||
|
|
||||||
/// Return ARC usage.
|
/// Return ARC usage.
|
||||||
#[cfg(feature = "zfs")]
|
#[cfg(feature = "zfs")]
|
||||||
pub(crate) fn get_arc_usage() -> Option<MemHarvest> {
|
pub(crate) fn get_arc_usage() -> Option<MemData> {
|
||||||
|
use std::num::NonZeroU64;
|
||||||
|
|
||||||
let (mem_total, mem_used) = {
|
let (mem_total, mem_used) = {
|
||||||
cfg_if::cfg_if! {
|
cfg_if::cfg_if! {
|
||||||
if #[cfg(target_os = "linux")] {
|
if #[cfg(target_os = "linux")] {
|
||||||
|
@ -63,12 +65,8 @@ pub(crate) fn get_arc_usage() -> Option<MemHarvest> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if mem_total > 0 {
|
NonZeroU64::new(mem_total).map(|total_bytes| MemData {
|
||||||
Some(MemHarvest {
|
total_bytes,
|
||||||
total_bytes: mem_total,
|
used_bytes: mem_used,
|
||||||
used_bytes: mem_used,
|
})
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,32 +1,27 @@
|
||||||
//! Collecting memory data using sysinfo.
|
//! Collecting memory data using sysinfo.
|
||||||
|
|
||||||
|
use std::num::NonZeroU64;
|
||||||
|
|
||||||
use sysinfo::System;
|
use sysinfo::System;
|
||||||
|
|
||||||
use crate::collection::memory::MemHarvest;
|
use crate::collection::memory::MemData;
|
||||||
|
|
||||||
/// Returns RAM usage.
|
#[inline]
|
||||||
pub(crate) fn get_ram_usage(sys: &System) -> Option<MemHarvest> {
|
fn get_usage(used: u64, total: u64) -> Option<MemData> {
|
||||||
let mem_used = sys.used_memory();
|
NonZeroU64::new(total).map(|total_bytes| MemData {
|
||||||
let mem_total = sys.total_memory();
|
total_bytes,
|
||||||
|
used_bytes: used,
|
||||||
Some(MemHarvest {
|
|
||||||
used_bytes: mem_used,
|
|
||||||
total_bytes: mem_total,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns RAM usage.
|
||||||
|
pub(crate) fn get_ram_usage(sys: &System) -> Option<MemData> {
|
||||||
|
get_usage(sys.used_memory(), sys.total_memory())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns SWAP usage.
|
/// Returns SWAP usage.
|
||||||
pub(crate) fn get_swap_usage(sys: &System) -> Option<MemHarvest> {
|
pub(crate) fn get_swap_usage(sys: &System) -> Option<MemData> {
|
||||||
let mem_used = sys.used_swap();
|
get_usage(sys.used_swap(), sys.total_swap())
|
||||||
let mem_total = sys.total_swap();
|
|
||||||
if mem_total > 0 {
|
|
||||||
Some(MemHarvest {
|
|
||||||
used_bytes: mem_used,
|
|
||||||
total_bytes: mem_total,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns cache usage. sysinfo has no way to do this directly but it should
|
/// Returns cache usage. sysinfo has no way to do this directly but it should
|
||||||
|
@ -37,12 +32,9 @@ pub(crate) fn get_swap_usage(sys: &System) -> Option<MemHarvest> {
|
||||||
/// Windows, this will always be 0. For more information, see [docs](https://docs.rs/sysinfo/latest/sysinfo/struct.System.html#method.available_memory)
|
/// Windows, this will always be 0. For more information, see [docs](https://docs.rs/sysinfo/latest/sysinfo/struct.System.html#method.available_memory)
|
||||||
/// and [memory explanation](https://askubuntu.com/questions/867068/what-is-available-memory-while-using-free-command)
|
/// and [memory explanation](https://askubuntu.com/questions/867068/what-is-available-memory-while-using-free-command)
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
pub(crate) fn get_cache_usage(sys: &System) -> Option<MemHarvest> {
|
pub(crate) fn get_cache_usage(sys: &System) -> Option<MemData> {
|
||||||
let mem_used = sys.available_memory().saturating_sub(sys.free_memory());
|
let mem_used = sys.available_memory().saturating_sub(sys.free_memory());
|
||||||
let mem_total = sys.total_memory();
|
let mem_total = sys.total_memory();
|
||||||
|
|
||||||
Some(MemHarvest {
|
get_usage(mem_used, mem_total)
|
||||||
total_bytes: mem_total,
|
|
||||||
used_bytes: mem_used,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::sync::OnceLock;
|
use std::{num::NonZeroU64, sync::OnceLock};
|
||||||
|
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use nvml_wrapper::{
|
use nvml_wrapper::{
|
||||||
|
@ -7,13 +7,13 @@ use nvml_wrapper::{
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::{filter::Filter, layout_manager::UsedWidgets},
|
app::{filter::Filter, layout_manager::UsedWidgets},
|
||||||
collection::{memory::MemHarvest, temperature::TempSensorData},
|
collection::{memory::MemData, temperature::TempSensorData},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub static NVML_DATA: OnceLock<Result<Nvml, NvmlError>> = OnceLock::new();
|
pub static NVML_DATA: OnceLock<Result<Nvml, NvmlError>> = OnceLock::new();
|
||||||
|
|
||||||
pub struct GpusData {
|
pub struct GpusData {
|
||||||
pub memory: Option<Vec<(String, MemHarvest)>>,
|
pub memory: Option<Vec<(String, MemData)>>,
|
||||||
pub temperature: Option<Vec<TempSensorData>>,
|
pub temperature: Option<Vec<TempSensorData>>,
|
||||||
pub procs: Option<(u64, Vec<HashMap<u32, (u64, u32)>>)>,
|
pub procs: Option<(u64, Vec<HashMap<u32, (u64, u32)>>)>,
|
||||||
}
|
}
|
||||||
|
@ -58,13 +58,15 @@ pub fn get_nvidia_vecs(
|
||||||
if let Ok(name) = device.name() {
|
if let Ok(name) = device.name() {
|
||||||
if widgets_to_harvest.use_mem {
|
if widgets_to_harvest.use_mem {
|
||||||
if let Ok(mem) = device.memory_info() {
|
if let Ok(mem) = device.memory_info() {
|
||||||
mem_vec.push((
|
if let Some(total_bytes) = NonZeroU64::new(mem.total) {
|
||||||
name.clone(),
|
mem_vec.push((
|
||||||
MemHarvest {
|
name.clone(),
|
||||||
total_bytes: mem.total,
|
MemData {
|
||||||
used_bytes: mem.used,
|
total_bytes,
|
||||||
},
|
used_bytes: mem.used,
|
||||||
));
|
},
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue