Add new option to allow for seeing cpu usage in processes as a percentage of current usage, rather than total
This commit is contained in:
parent
d0a7a0dd72
commit
e5749234a2
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue