summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClementTsang <clementjhtsang@gmail.com>2019-12-31 22:24:54 -0500
committerClementTsang <clementjhtsang@gmail.com>2019-12-31 22:24:54 -0500
commite5749234a2a96427a04d647a14c92c3bb1e89809 (patch)
tree808dcbb94feb42cc1b592bdc6286bee9704b7e25
parentd0a7a0dd72b6b23995a725fd460f2d97b6eff11e (diff)
Add new option to allow for seeing cpu usage in processes as a percentage of current usage, rather than total
-rw-r--r--README.md2
-rw-r--r--src/app.rs3
-rw-r--r--src/app/data_collection.rs14
-rw-r--r--src/app/data_collection/processes.rs21
-rw-r--r--src/main.rs4
5 files changed, 36 insertions, 8 deletions
diff --git a/README.md b/README.md
index 3f1b7379..bf6b277a 100644
--- a/README.md
+++ b/README.md
@@ -46,6 +46,8 @@ Note that all options and keybindings on GitHub may reflect the current developm
- `-l`, `--left_legend` will move external table legends to the left side rather than the right side. Right side is default.
+- `-u`, `--current_usage` will make a process' CPU usage be based on the current total CPU usage, rather than assuming 100% CPU usage. Only affects Linux.
+
### Keybindings
#### General
diff --git a/src/app.rs b/src/app.rs
index c74d6ce7..33a6e40a 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -47,12 +47,14 @@ pub struct App {
pub show_help: bool,
pub is_frozen: bool,
pub left_legend: bool,
+ pub use_current_cpu_total: bool,
last_key_press: Instant,
}
impl App {
pub fn new(
show_average_cpu: bool, temperature_type: temperature::TemperatureType, update_rate_in_milliseconds: u64, use_dot: bool, left_legend: bool,
+ use_current_cpu_total: bool,
) -> App {
App {
process_sorting_type: processes::ProcessSorting::CPU,
@@ -76,6 +78,7 @@ impl App {
show_help: false,
is_frozen: false,
left_legend,
+ use_current_cpu_total,
last_key_press: Instant::now(),
}
}
diff --git a/src/app/data_collection.rs b/src/app/data_collection.rs
index 325c83e7..64a1f024 100644
--- a/src/app/data_collection.rs
+++ b/src/app/data_collection.rs
@@ -49,6 +49,7 @@ pub struct DataState {
prev_net_access_time: Instant,
temperature_type: temperature::TemperatureType,
last_clean: Instant, // Last time stale data was cleared
+ use_current_cpu_total: bool,
}
impl Default for DataState {
@@ -66,6 +67,7 @@ impl Default for DataState {
prev_net_access_time: Instant::now(),
temperature_type: temperature::TemperatureType::Celsius,
last_clean: Instant::now(),
+ use_current_cpu_total: false,
}
}
}
@@ -75,6 +77,10 @@ impl DataState {
self.temperature_type = temperature_type;
}
+ pub fn set_use_current_cpu_total(&mut self, use_current_cpu_total: bool) {
+ self.use_current_cpu_total = use_current_cpu_total;
+ }
+
pub fn init(&mut self) {
self.sys.refresh_all();
}
@@ -104,7 +110,13 @@ impl DataState {
push_if_valid(&mem::get_mem_data_list().await, &mut self.data.memory);
push_if_valid(&mem::get_swap_data_list().await, &mut self.data.swap);
set_if_valid(
- &processes::get_sorted_processes_list(&self.sys, &mut self.prev_idle, &mut self.prev_non_idle, &mut self.prev_pid_stats),
+ &processes::get_sorted_processes_list(
+ &self.sys,
+ &mut self.prev_idle,
+ &mut self.prev_non_idle,
+ &mut self.prev_pid_stats,
+ self.use_current_cpu_total,
+ ),
&mut self.data.list_of_processes,
);
diff --git a/src/app/data_collection/processes.rs b/src/app/data_collection/processes.rs
index 0eda01f5..16e612c1 100644
--- a/src/app/data_collection/processes.rs
+++ b/src/app/data_collection/processes.rs
@@ -82,7 +82,7 @@ fn cpu_usage_calculation(prev_idle: &mut f64, prev_non_idle: &mut f64) -> error:
let cpu_percentage = if total_delta != 0_f64 { result / total_delta } else { 0_f64 };
- Ok((result, cpu_percentage)) // This works, REALLY damn well. The percentage check is within like 2% of the sysinfo one.
+ Ok((result, cpu_percentage))
}
fn get_ordering<T: std::cmp::PartialOrd>(a_val: T, b_val: T, reverse_order: bool) -> std::cmp::Ordering {
@@ -104,7 +104,7 @@ fn get_ordering<T: std::cmp::PartialOrd>(a_val: T, b_val: T, reverse_order: bool
}
Ordering::Equal => Ordering::Equal,
},
- None => Ordering::Equal, // I don't really like this but I think it's fine...
+ None => Ordering::Equal,
}
}
@@ -125,7 +125,9 @@ fn get_process_cpu_stats(pid: u32) -> std::io::Result<f64> {
}
/// Note that cpu_percentage should be represented WITHOUT the \times 100 factor!
-fn linux_cpu_usage(pid: u32, cpu_usage: f64, cpu_percentage: f64, previous_pid_stats: &mut HashMap<String, (f64, Instant)>) -> std::io::Result<f64> {
+fn linux_cpu_usage(
+ pid: u32, cpu_usage: f64, cpu_percentage: f64, previous_pid_stats: &mut HashMap<String, (f64, Instant)>, use_current_cpu_total: bool,
+) -> std::io::Result<f64> {
// Based heavily on https://stackoverflow.com/a/23376195 and https://stackoverflow.com/a/1424556
let before_proc_val: f64 = if previous_pid_stats.contains_key(&pid.to_string()) {
previous_pid_stats.get(&pid.to_string()).unwrap_or(&(0_f64, Instant::now())).0
@@ -145,11 +147,15 @@ fn linux_cpu_usage(pid: u32, cpu_usage: f64, cpu_percentage: f64, previous_pid_s
let entry = previous_pid_stats.entry(pid.to_string()).or_insert((after_proc_val, Instant::now()));
*entry = (after_proc_val, Instant::now());
- Ok((after_proc_val - before_proc_val) / cpu_usage * 100_f64 * cpu_percentage)
+ if use_current_cpu_total {
+ Ok((after_proc_val - before_proc_val) / cpu_usage * 100_f64)
+ } else {
+ Ok((after_proc_val - before_proc_val) / cpu_usage * 100_f64 * cpu_percentage)
+ }
}
fn convert_ps(
- process: &str, cpu_usage: f64, cpu_percentage: f64, prev_pid_stats: &mut HashMap<String, (f64, Instant)>,
+ process: &str, cpu_usage: f64, cpu_percentage: f64, prev_pid_stats: &mut HashMap<String, (f64, Instant)>, use_current_cpu_total: bool,
) -> std::io::Result<ProcessData> {
if process.trim().to_string().is_empty() {
return Ok(ProcessData {
@@ -170,12 +176,13 @@ fn convert_ps(
command,
mem_usage_percent,
mem_usage_kb: None,
- cpu_usage_percent: linux_cpu_usage(pid, cpu_usage, cpu_percentage, prev_pid_stats)?,
+ cpu_usage_percent: linux_cpu_usage(pid, cpu_usage, cpu_percentage, prev_pid_stats, use_current_cpu_total)?,
})
}
pub fn get_sorted_processes_list(
sys: &System, prev_idle: &mut f64, prev_non_idle: &mut f64, prev_pid_stats: &mut std::collections::HashMap<String, (f64, Instant)>,
+ use_current_cpu_total: bool,
) -> crate::utils::error::Result<Vec<ProcessData>> {
let mut process_vector: Vec<ProcessData> = Vec::new();
@@ -191,7 +198,7 @@ pub fn get_sorted_processes_list(
let process_stream = split_string.collect::<Vec<&str>>();
for process in process_stream {
- if let Ok(process_object) = convert_ps(process, cpu_usage, cpu_percentage, prev_pid_stats) {
+ if let Ok(process_object) = convert_ps(process, cpu_usage, cpu_percentage, prev_pid_stats, use_current_cpu_total) {
if !process_object.command.is_empty() {
process_vector.push(process_object);
}
diff --git a/src/main.rs b/src/main.rs
index 1f2e9f84..dc54281e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -66,6 +66,7 @@ fn main() -> error::Result<()> {
)
(@arg RATE_MILLIS: -r --rate +takes_value "Sets a refresh rate in milliseconds; the minimum is 250ms, defaults to 1000ms. Smaller values may take more resources.")
(@arg LEFT_LEGEND: -l --left_legend "Puts external chart legends on the left side rather than the default right side.")
+ (@arg USE_CURR_USAGE: -u --current_usage "Within Linux, sets a process' CPU usage to be based on the total current CPU usage, rather than assuming 100% usage.")
//(@arg CONFIG_LOCATION: -co --config +takes_value "Sets the location of the config file. Expects a config file in the JSON format.")
//(@arg BASIC_MODE: -b --basic "Sets bottom to basic mode, not showing graphs and only showing basic tables.")
)
@@ -107,6 +108,7 @@ fn main() -> error::Result<()> {
let show_average_cpu = matches.is_present("AVG_CPU");
let use_dot = matches.is_present("DOT_MARKER");
let left_legend = matches.is_present("LEFT_LEGEND");
+ let use_current_cpu_total = matches.is_present("USE_CURR_USAGE");
// Create "app" struct, which will control most of the program and store settings/state
let mut app = app::App::new(
@@ -115,6 +117,7 @@ fn main() -> error::Result<()> {
update_rate_in_milliseconds as u64,
use_dot,
left_legend,
+ use_current_cpu_total,
);
// Set up up tui and crossterm
@@ -169,6 +172,7 @@ fn main() -> error::Result<()> {
let mut data_state = data_collection::DataState::default();
data_state.init();
data_state.set_temperature_type(temp_type);
+ data_state.set_use_current_cpu_total(use_current_cpu_total);
loop {
if let Ok(message) = rrx.try_recv() {
match message {