From 574c2c1df7616ed9f80831360cd97aa2d0d9ae44 Mon Sep 17 00:00:00 2001 From: Clement Tsang <34804052+ClementTsang@users.noreply.github.com> Date: Sun, 9 May 2021 01:39:42 -0400 Subject: [PATCH] change: switch from sysinfo to heim for cpu usage in macOS and Windows (#467) Due to #404, I've just moved all CPU usage calculations over to heim. --- CHANGELOG.md | 2 ++ Cargo.toml | 6 ++-- src/app/data_harvester.rs | 29 ++++----------- src/app/data_harvester/cpu.rs | 66 +++++++++++++---------------------- 4 files changed, 37 insertions(+), 66 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92e6af53..a0600706 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -65,6 +65,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - [#425](https://github.com/ClementTsang/bottom/pull/425): Fixed a bug allowing grouped mode in tree mode if already in grouped mode. +- [#467](https://github.com/ClementTsang/bottom/pull/467): Switched CPU usage data source to fix a bug on Windows where occasionally CPU usage would be stuck at 0%. + ## [0.5.7] - 2021-01-30 ## Bug Fixes diff --git a/Cargo.toml b/Cargo.toml index 7745e71d..fa61e6e2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ ctrlc = { version = "3.1.9", features = ["termination"] } clap = "2.33" dirs-next = "2.0.0" futures = "0.3.14" +futures-timer = "3.0.2" fxhash = "0.2.1" indexmap = "1.6.2" itertools = "0.10.0" @@ -68,13 +69,12 @@ libc = "0.2.86" [target.'cfg(target_os = "linux")'.dependencies] heim = { version = "0.1.0-rc.1", features = ["cpu", "disk", "memory", "net", "sensors"] } -futures-timer = "3.0.2" [target.'cfg(target_os = "macos")'.dependencies] -heim = { version = "0.1.0-rc.1", features = ["disk", "memory", "net"] } +heim = { version = "0.1.0-rc.1", features = ["cpu", "disk", "memory", "net"] } [target.'cfg(target_os = "windows")'.dependencies] -heim = { version = "0.1.0-rc.1", features = ["disk", "memory"] } +heim = { version = "0.1.0-rc.1", features = ["cpu", "disk", "memory"] } winapi = "0.3.9" [dev-dependencies] diff --git a/src/app/data_harvester.rs b/src/app/data_harvester.rs index 65fc680f..209cbb05 100644 --- a/src/app/data_harvester.rs +++ b/src/app/data_harvester.rs @@ -80,9 +80,7 @@ pub struct DataCollector { pub data: Data, #[cfg(not(target_os = "linux"))] sys: System, - #[cfg(target_os = "linux")] previous_cpu_times: Vec<(cpu::PastCpuWork, cpu::PastCpuTotal)>, - #[cfg(target_os = "linux")] previous_average_cpu_time: Option<(cpu::PastCpuWork, cpu::PastCpuTotal)>, #[cfg(target_os = "linux")] pid_mapping: FxHashMap, @@ -111,9 +109,7 @@ impl DataCollector { data: Data::default(), #[cfg(not(target_os = "linux"))] sys: System::new_with_specifics(sysinfo::RefreshKind::new()), - #[cfg(target_os = "linux")] previous_cpu_times: vec![], - #[cfg(target_os = "linux")] previous_average_cpu_time: None, #[cfg(target_os = "linux")] pid_mapping: FxHashMap::default(), @@ -216,9 +212,6 @@ impl DataCollector { pub async fn update_data(&mut self) { #[cfg(not(target_os = "linux"))] { - if self.widgets_to_harvest.use_cpu { - self.sys.refresh_cpu(); - } if self.widgets_to_harvest.use_proc { self.sys.refresh_processes(); } @@ -235,22 +228,14 @@ impl DataCollector { // CPU if self.widgets_to_harvest.use_cpu { - #[cfg(not(target_os = "linux"))] + if let Ok(cpu_data) = cpu::get_cpu_data_list( + self.show_average_cpu, + &mut self.previous_cpu_times, + &mut self.previous_average_cpu_time, + ) + .await { - self.data.cpu = Some(cpu::get_cpu_data_list(&self.sys, self.show_average_cpu)); - } - - #[cfg(target_os = "linux")] - { - if let Ok(cpu_data) = cpu::get_cpu_data_list( - self.show_average_cpu, - &mut self.previous_cpu_times, - &mut self.previous_average_cpu_time, - ) - .await - { - self.data.cpu = Some(cpu_data); - } + self.data.cpu = Some(cpu_data); } #[cfg(target_family = "unix")] diff --git a/src/app/data_harvester/cpu.rs b/src/app/data_harvester/cpu.rs index bbc17509..61e79e28 100644 --- a/src/app/data_harvester/cpu.rs +++ b/src/app/data_harvester/cpu.rs @@ -10,56 +10,40 @@ pub type CpuHarvest = Vec; pub type PastCpuWork = f64; pub type PastCpuTotal = f64; -#[cfg(not(target_os = "linux"))] -use sysinfo::{ProcessorExt, System, SystemExt}; - -#[cfg(not(target_os = "linux"))] -pub fn get_cpu_data_list(sys: &System, show_average_cpu: bool) -> CpuHarvest { - let cpu_data = sys.get_processors(); - let avg_cpu_usage = sys.get_global_processor_info().get_cpu_usage(); - let mut cpu_vec = vec![]; - - if show_average_cpu { - cpu_vec.push(CpuData { - cpu_prefix: "AVG".to_string(), - cpu_count: None, - cpu_usage: avg_cpu_usage as f64, - }); - } - - for (itx, cpu) in cpu_data.iter().enumerate() { - cpu_vec.push(CpuData { - cpu_prefix: "CPU".to_string(), - cpu_count: Some(itx), - cpu_usage: f64::from(cpu.get_cpu_usage()), - }); - } - - cpu_vec -} - -#[cfg(target_os = "linux")] pub async fn get_cpu_data_list( show_average_cpu: bool, previous_cpu_times: &mut Vec<(PastCpuWork, PastCpuTotal)>, previous_average_cpu_time: &mut Option<(PastCpuWork, PastCpuTotal)>, ) -> crate::error::Result { use futures::StreamExt; + #[cfg(target_os = "linux")] use heim::cpu::os::linux::CpuTimeExt; use std::collections::VecDeque; fn convert_cpu_times(cpu_time: &heim::cpu::CpuTime) -> (f64, f64) { - let working_time: f64 = (cpu_time.user() - + cpu_time.nice() - + cpu_time.system() - + cpu_time.irq() - + cpu_time.soft_irq() - + cpu_time.steal()) - .get::(); - ( - working_time, - working_time - + (cpu_time.idle() + cpu_time.io_wait()).get::(), - ) + #[cfg(not(target_os = "linux"))] + { + let working_time: f64 = + (cpu_time.user() + cpu_time.system()).get::(); + ( + working_time, + working_time + cpu_time.idle().get::(), + ) + } + #[cfg(target_os = "linux")] + { + let working_time: f64 = (cpu_time.user() + + cpu_time.nice() + + cpu_time.system() + + cpu_time.irq() + + cpu_time.soft_irq() + + cpu_time.steal()) + .get::(); + ( + working_time, + working_time + + (cpu_time.idle() + cpu_time.io_wait()).get::(), + ) + } } fn calculate_cpu_usage_percentage(