mirror of
https://github.com/ClementTsang/bottom.git
synced 2025-09-25 18:49:06 +02:00
Tried to fix process cpu usage... and reduce total cpu usage of program.
This commit is contained in:
parent
8ba4674560
commit
939e2d1d77
24
TODO.md
24
TODO.md
@ -8,30 +8,14 @@
|
|||||||
|
|
||||||
* Write tui display, charting
|
* Write tui display, charting
|
||||||
|
|
||||||
|
* Add custom error because it's really messy
|
||||||
|
|
||||||
* Keybindings
|
* Keybindings
|
||||||
|
|
||||||
* Test for Windows support
|
* Test for Windows support, mac support
|
||||||
|
|
||||||
* Efficiency!!! Make sure no wasted hashmaps, use references, etc.
|
* Efficiency!!! Make sure no wasted hashmaps, use references, etc.
|
||||||
|
|
||||||
## Planned features: (copy of gotop)
|
|
||||||
|
|
||||||
* CPU usage monitor
|
|
||||||
|
|
||||||
* Total disk usage
|
|
||||||
|
|
||||||
* Memory usage
|
|
||||||
|
|
||||||
* Temperature
|
|
||||||
|
|
||||||
* Processes
|
|
||||||
|
|
||||||
* Network usage
|
|
||||||
|
|
||||||
## Other possible features
|
|
||||||
|
|
||||||
* Potentially process managing? Depends on the libraries...
|
* Potentially process managing? Depends on the libraries...
|
||||||
|
|
||||||
* Rearranging?
|
* Filtering in processes (ie: search)
|
||||||
|
|
||||||
* Filtering in processes along with sorting
|
|
||||||
|
0
src/error.rs
Normal file
0
src/error.rs
Normal file
15
src/main.rs
15
src/main.rs
@ -25,7 +25,7 @@ async fn main() -> Result<(), io::Error> {
|
|||||||
let backend = CrosstermBackend::with_alternate_screen(screen)?;
|
let backend = CrosstermBackend::with_alternate_screen(screen)?;
|
||||||
let mut terminal = Terminal::new(backend)?;
|
let mut terminal = Terminal::new(backend)?;
|
||||||
|
|
||||||
let tick_rate_in_milliseconds : u64 = 220;
|
let tick_rate_in_milliseconds : u64 = 250;
|
||||||
let update_rate_in_milliseconds : u64 = 1000;
|
let update_rate_in_milliseconds : u64 = 1000;
|
||||||
|
|
||||||
let log = init_logger();
|
let log = init_logger();
|
||||||
@ -129,14 +129,13 @@ fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, app_data :
|
|||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let mem_total_mb = app_data.memory.mem_total_in_mb as f64;
|
|
||||||
let process_rows = app_data.list_of_processes.iter().map(|process| {
|
let process_rows = app_data.list_of_processes.iter().map(|process| {
|
||||||
Row::StyledData(
|
Row::StyledData(
|
||||||
vec![
|
vec![
|
||||||
process.pid.to_string(),
|
process.pid.to_string(),
|
||||||
process.command.to_string(),
|
process.command.to_string(),
|
||||||
format!("{:.2}%", process.cpu_usage_percent),
|
format!("{:.2}%", process.cpu_usage_percent),
|
||||||
format!("{:.2}%", process.mem_usage_in_mb as f64 / mem_total_mb * 100_f64),
|
format!("{:.2}%", process.mem_usage_percent),
|
||||||
]
|
]
|
||||||
.into_iter(),
|
.into_iter(),
|
||||||
Style::default().fg(Color::LightGreen),
|
Style::default().fg(Color::LightGreen),
|
||||||
@ -198,14 +197,14 @@ fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, app_data :
|
|||||||
Table::new(["Sensor", "Temperature"].iter(), temperature_rows)
|
Table::new(["Sensor", "Temperature"].iter(), temperature_rows)
|
||||||
.block(Block::default().title("Temperatures").borders(Borders::ALL))
|
.block(Block::default().title("Temperatures").borders(Borders::ALL))
|
||||||
.header_style(Style::default().fg(Color::LightBlue))
|
.header_style(Style::default().fg(Color::LightBlue))
|
||||||
.widths(&[25, 25])
|
.widths(&[15, 5])
|
||||||
.render(&mut f, middle_divided_chunk[0]);
|
.render(&mut f, middle_divided_chunk[0]);
|
||||||
|
|
||||||
// Disk usage table
|
// Disk usage table
|
||||||
Table::new(["Disk", "Mount", "Used", "Total", "Free"].iter(), disk_rows)
|
Table::new(["Disk", "Mount", "Used", "Total", "Free"].iter(), disk_rows)
|
||||||
.block(Block::default().title("Disk Usage").borders(Borders::ALL))
|
.block(Block::default().title("Disk Usage").borders(Borders::ALL))
|
||||||
.header_style(Style::default().fg(Color::LightBlue))
|
.header_style(Style::default().fg(Color::LightBlue))
|
||||||
.widths(&[25, 25, 10, 10, 10])
|
.widths(&[15, 10, 5, 5, 5])
|
||||||
.render(&mut f, middle_divided_chunk[1]);
|
.render(&mut f, middle_divided_chunk[1]);
|
||||||
|
|
||||||
// IO graph
|
// IO graph
|
||||||
@ -215,7 +214,7 @@ fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, app_data :
|
|||||||
Block::default().title("Network").borders(Borders::ALL).render(&mut f, bottom_chunks[0]);
|
Block::default().title("Network").borders(Borders::ALL).render(&mut f, bottom_chunks[0]);
|
||||||
|
|
||||||
// Processes table
|
// Processes table
|
||||||
Table::new(["PID", "Command", "CPU%", "Mem%"].iter(), process_rows)
|
Table::new(["PID", "Name", "CPU%", "Mem%"].iter(), process_rows)
|
||||||
.block(Block::default().title("Processes").borders(Borders::ALL))
|
.block(Block::default().title("Processes").borders(Borders::ALL))
|
||||||
.header_style(Style::default().fg(Color::LightBlue))
|
.header_style(Style::default().fg(Color::LightBlue))
|
||||||
.widths(&[5, 15, 10, 10])
|
.widths(&[5, 15, 10, 10])
|
||||||
@ -226,6 +225,7 @@ fn draw_data<B : tui::backend::Backend>(terminal : &mut Terminal<B>, app_data :
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn init_logger() -> Result<(), fern::InitError> {
|
fn init_logger() -> Result<(), fern::InitError> {
|
||||||
|
if cfg!(debug_assertions) {
|
||||||
fern::Dispatch::new()
|
fern::Dispatch::new()
|
||||||
.format(|out, message, record| {
|
.format(|out, message, record| {
|
||||||
out.finish(format_args!(
|
out.finish(format_args!(
|
||||||
@ -239,12 +239,13 @@ fn init_logger() -> Result<(), fern::InitError> {
|
|||||||
.level(log::LevelFilter::Debug)
|
.level(log::LevelFilter::Debug)
|
||||||
.chain(fern::log_file("debug.log")?)
|
.chain(fern::log_file("debug.log")?)
|
||||||
.apply()?;
|
.apply()?;
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_debug(result_log : &Result<(), fern::InitError>, message : &str) {
|
fn try_debug(result_log : &Result<(), fern::InitError>, message : &str) {
|
||||||
if result_log.is_ok() {
|
if cfg!(debug_assertions) && result_log.is_ok() {
|
||||||
debug!("{}", message);
|
debug!("{}", message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,6 +51,7 @@ impl Default for DataState {
|
|||||||
|
|
||||||
impl DataState {
|
impl DataState {
|
||||||
pub async fn update_data(&mut self) {
|
pub async fn update_data(&mut self) {
|
||||||
|
debug!("Start updating...");
|
||||||
self.sys.refresh_system();
|
self.sys.refresh_system();
|
||||||
self.sys.refresh_network();
|
self.sys.refresh_network();
|
||||||
|
|
||||||
@ -59,13 +60,15 @@ impl DataState {
|
|||||||
set_if_valid(&cpu::get_cpu_data_list(&self.sys), &mut self.data.list_of_cpu_packages);
|
set_if_valid(&cpu::get_cpu_data_list(&self.sys), &mut self.data.list_of_cpu_packages);
|
||||||
|
|
||||||
// TODO: We can convert this to a multi-threaded task...
|
// TODO: We can convert this to a multi-threaded task...
|
||||||
set_if_valid(&processes::get_sorted_processes_list().await, &mut self.data.list_of_processes);
|
set_if_valid(&mem::get_mem_data_list().await, &mut self.data.memory);
|
||||||
|
set_if_valid(&mem::get_swap_data_list().await, &mut self.data.swap);
|
||||||
|
set_if_valid(&processes::get_sorted_processes_list(self.data.memory.mem_total_in_mb).await, &mut self.data.list_of_processes);
|
||||||
|
|
||||||
set_if_valid(&disks::get_disk_usage_list().await, &mut self.data.list_of_disks);
|
set_if_valid(&disks::get_disk_usage_list().await, &mut self.data.list_of_disks);
|
||||||
set_if_valid(&disks::get_io_usage_list(false).await, &mut self.data.list_of_io);
|
set_if_valid(&disks::get_io_usage_list(false).await, &mut self.data.list_of_io);
|
||||||
set_if_valid(&disks::get_io_usage_list(true).await, &mut self.data.list_of_physical_io);
|
set_if_valid(&disks::get_io_usage_list(true).await, &mut self.data.list_of_physical_io);
|
||||||
set_if_valid(&mem::get_mem_data_list().await, &mut self.data.memory);
|
|
||||||
set_if_valid(&mem::get_swap_data_list().await, &mut self.data.swap);
|
|
||||||
set_if_valid(&temperature::get_temperature_data().await, &mut self.data.list_of_temperature);
|
set_if_valid(&temperature::get_temperature_data().await, &mut self.data.list_of_temperature);
|
||||||
|
debug!("End updating...");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,9 +76,9 @@ impl<'a> App<'a> {
|
|||||||
pub fn new(title : &str) -> App {
|
pub fn new(title : &str) -> App {
|
||||||
App {
|
App {
|
||||||
title,
|
title,
|
||||||
process_sorting_type : processes::ProcessSorting::NAME, // TODO: Change this based on input args...
|
process_sorting_type : processes::ProcessSorting::CPU, // TODO: Change this based on input args... basically set this on app creation
|
||||||
should_quit : false,
|
should_quit : false,
|
||||||
process_sorting_reverse : false,
|
process_sorting_reverse : true,
|
||||||
to_be_resorted : false,
|
to_be_resorted : false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -83,24 +86,48 @@ impl<'a> App<'a> {
|
|||||||
pub fn on_key(&mut self, c : char) {
|
pub fn on_key(&mut self, c : char) {
|
||||||
match c {
|
match c {
|
||||||
'q' => self.should_quit = true,
|
'q' => self.should_quit = true,
|
||||||
|
'h' => self.on_right(),
|
||||||
|
'j' => self.on_down(),
|
||||||
|
'k' => self.on_up(),
|
||||||
|
'l' => self.on_left(),
|
||||||
'c' => {
|
'c' => {
|
||||||
self.process_sorting_type = processes::ProcessSorting::CPU; // TODO: Change this such that reversing can be done by just hitting "c" twice...
|
match self.process_sorting_type {
|
||||||
|
processes::ProcessSorting::CPU => self.process_sorting_reverse = !self.process_sorting_reverse,
|
||||||
|
_ => {
|
||||||
|
self.process_sorting_type = processes::ProcessSorting::CPU;
|
||||||
|
self.process_sorting_reverse = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
self.to_be_resorted = true;
|
self.to_be_resorted = true;
|
||||||
}
|
}
|
||||||
'm' => {
|
'm' => {
|
||||||
|
match self.process_sorting_type {
|
||||||
|
processes::ProcessSorting::MEM => self.process_sorting_reverse = !self.process_sorting_reverse,
|
||||||
|
_ => {
|
||||||
self.process_sorting_type = processes::ProcessSorting::MEM;
|
self.process_sorting_type = processes::ProcessSorting::MEM;
|
||||||
|
self.process_sorting_reverse = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
self.to_be_resorted = true;
|
self.to_be_resorted = true;
|
||||||
}
|
}
|
||||||
'p' => {
|
'p' => {
|
||||||
|
match self.process_sorting_type {
|
||||||
|
processes::ProcessSorting::PID => self.process_sorting_reverse = !self.process_sorting_reverse,
|
||||||
|
_ => {
|
||||||
self.process_sorting_type = processes::ProcessSorting::PID;
|
self.process_sorting_type = processes::ProcessSorting::PID;
|
||||||
|
self.process_sorting_reverse = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
self.to_be_resorted = true;
|
self.to_be_resorted = true;
|
||||||
}
|
}
|
||||||
'n' => {
|
'n' => {
|
||||||
|
match self.process_sorting_type {
|
||||||
|
processes::ProcessSorting::NAME => self.process_sorting_reverse = !self.process_sorting_reverse,
|
||||||
|
_ => {
|
||||||
self.process_sorting_type = processes::ProcessSorting::NAME;
|
self.process_sorting_type = processes::ProcessSorting::NAME;
|
||||||
self.to_be_resorted = true;
|
self.process_sorting_reverse = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
'r' => {
|
|
||||||
self.process_sorting_reverse = !self.process_sorting_reverse;
|
|
||||||
self.to_be_resorted = true;
|
self.to_be_resorted = true;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -2,6 +2,7 @@ use heim_common::{
|
|||||||
prelude::{StreamExt, TryStreamExt},
|
prelude::{StreamExt, TryStreamExt},
|
||||||
units,
|
units,
|
||||||
};
|
};
|
||||||
|
use std::process::Command;
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -17,7 +18,7 @@ pub enum ProcessSorting {
|
|||||||
pub struct ProcessData {
|
pub struct ProcessData {
|
||||||
pub pid : u32,
|
pub pid : u32,
|
||||||
pub cpu_usage_percent : f64,
|
pub cpu_usage_percent : f64,
|
||||||
pub mem_usage_in_mb : u64,
|
pub mem_usage_percent : f64,
|
||||||
pub command : String,
|
pub command : String,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,16 +44,77 @@ fn get_ordering<T : std::cmp::PartialOrd>(a_val : T, b_val : T, reverse_order :
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn cpu_usage(process : heim::process::Process) -> heim::process::ProcessResult<(heim::process::Process, heim_common::units::Ratio)> {
|
async fn non_linux_cpu_usage(process : heim::process::Process) -> heim::process::ProcessResult<(heim::process::Process, heim_common::units::Ratio)> {
|
||||||
let usage_1 = process.cpu_usage().await?;
|
let usage_1 = process.cpu_usage().await?;
|
||||||
futures_timer::Delay::new(std::time::Duration::from_millis(150)).await?;
|
futures_timer::Delay::new(std::time::Duration::from_millis(100)).await?;
|
||||||
let usage_2 = process.cpu_usage().await?;
|
let usage_2 = process.cpu_usage().await?;
|
||||||
|
|
||||||
Ok((process, usage_2 - usage_1))
|
Ok((process, usage_2 - usage_1))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_sorted_processes_list() -> Result<Vec<ProcessData>, heim::Error> {
|
fn get_process_cpu_stats(pid : u32) -> std::io::Result<f64> {
|
||||||
let mut process_stream = heim::process::processes().map_ok(cpu_usage).try_buffer_unordered(std::usize::MAX);
|
let mut path = std::path::PathBuf::new();
|
||||||
|
path.push("/proc");
|
||||||
|
path.push(&pid.to_string());
|
||||||
|
path.push("stat");
|
||||||
|
|
||||||
|
let stat_results = std::fs::read_to_string(path)?;
|
||||||
|
let val = stat_results.split_whitespace().collect::<Vec<&str>>();
|
||||||
|
Ok(val[13].parse::<f64>().unwrap_or(0_f64) + val[14].parse::<f64>().unwrap_or(0_f64))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_cpu_use_val() -> std::io::Result<f64> {
|
||||||
|
let mut path = std::path::PathBuf::new();
|
||||||
|
path.push("/proc");
|
||||||
|
path.push("stat");
|
||||||
|
|
||||||
|
let stat_results = std::fs::read_to_string(path)?;
|
||||||
|
let first_line = stat_results.split('\n').collect::<Vec<&str>>()[0];
|
||||||
|
let val = first_line.split_whitespace().collect::<Vec<&str>>();
|
||||||
|
Ok(val[0].parse::<f64>().unwrap_or(0_f64) + val[1].parse::<f64>().unwrap_or(0_f64) + val[2].parse::<f64>().unwrap_or(0_f64) + val[3].parse::<f64>().unwrap_or(0_f64))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn linux_cpu_usage(pid : u32) -> std::io::Result<f64> {
|
||||||
|
// Based heavily on https://stackoverflow.com/a/23376195 and https://stackoverflow.com/a/1424556
|
||||||
|
let before_proc_val = get_process_cpu_stats(pid)?;
|
||||||
|
let before_cpu_val = get_cpu_use_val()?;
|
||||||
|
futures_timer::Delay::new(std::time::Duration::from_millis(1000)).await.unwrap();
|
||||||
|
let after_proc_val = get_process_cpu_stats(pid)?;
|
||||||
|
let after_cpu_val = get_cpu_use_val()?;
|
||||||
|
|
||||||
|
Ok((after_proc_val - before_proc_val) / (after_cpu_val - before_cpu_val) * 100_f64)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn convert_ps(process : &str) -> std::io::Result<ProcessData> {
|
||||||
|
let mut result = process.split_whitespace();
|
||||||
|
let pid = result.next().unwrap_or("").parse::<u32>().unwrap_or(0);
|
||||||
|
Ok(ProcessData {
|
||||||
|
pid,
|
||||||
|
command : result.next().unwrap_or("").to_string(),
|
||||||
|
mem_usage_percent : result.next().unwrap_or("").parse::<f64>().unwrap_or(0_f64),
|
||||||
|
cpu_usage_percent : linux_cpu_usage(pid).await?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn get_sorted_processes_list(total_mem : u64) -> Result<Vec<ProcessData>, heim::Error> {
|
||||||
|
let mut process_vector : Vec<ProcessData> = Vec::new();
|
||||||
|
|
||||||
|
if cfg!(target_os = "linux") {
|
||||||
|
// Linux specific - this is a massive pain... ugh.
|
||||||
|
let ps_result = Command::new("ps").args(&["-axo", "pid,comm,%mem", "--noheader"]).output().expect("Failed to execute.");
|
||||||
|
let ps_stdout = String::from_utf8_lossy(&ps_result.stdout);
|
||||||
|
let split_string = ps_stdout.split('\n');
|
||||||
|
let mut process_stream = futures::stream::iter::<_>(split_string.collect::<Vec<&str>>()).map(convert_ps).buffer_unordered(std::usize::MAX);
|
||||||
|
|
||||||
|
while let Some(process) = process_stream.next().await {
|
||||||
|
if let Ok(process) = process {
|
||||||
|
process_vector.push(process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if cfg!(target_os = "windows") {
|
||||||
|
// Windows
|
||||||
|
let mut process_stream = heim::process::processes().map_ok(non_linux_cpu_usage).try_buffer_unordered(std::usize::MAX);
|
||||||
|
|
||||||
let mut process_vector : Vec<ProcessData> = Vec::new();
|
let mut process_vector : Vec<ProcessData> = Vec::new();
|
||||||
while let Some(process) = process_stream.next().await {
|
while let Some(process) = process_stream.next().await {
|
||||||
@ -60,34 +122,42 @@ pub async fn get_sorted_processes_list() -> Result<Vec<ProcessData>, heim::Error
|
|||||||
let (process, cpu_usage) = process;
|
let (process, cpu_usage) = process;
|
||||||
let mem_measurement = process.memory().await;
|
let mem_measurement = process.memory().await;
|
||||||
if let Ok(mem_measurement) = mem_measurement {
|
if let Ok(mem_measurement) = mem_measurement {
|
||||||
/*
|
|
||||||
// Unsure whether I want to implement this by grouping together process names...?
|
|
||||||
let mut process_info = process_hashmap.entry(command_name.to_string()).or_insert(ProcessInfo {
|
|
||||||
command : command_name,
|
|
||||||
pid : process.pid() as u32,
|
|
||||||
cpu_usage_percent : cpu_usage.get::<units::ratio::percent>(),
|
|
||||||
mem_usage_in_mb : mem_measurement.rss().get::<units::information::megabyte>(),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
process_vector.push(ProcessData {
|
process_vector.push(ProcessData {
|
||||||
command : process.name().await.unwrap_or_else(|_| "".to_string()),
|
command : process.name().await.unwrap_or_else(|_| "".to_string()),
|
||||||
pid : process.pid() as u32,
|
pid : process.pid() as u32,
|
||||||
cpu_usage_percent : f64::from(cpu_usage.get::<units::ratio::percent>()),
|
cpu_usage_percent : f64::from(cpu_usage.get::<units::ratio::percent>()),
|
||||||
mem_usage_in_mb : mem_measurement.rss().get::<units::information::megabyte>(),
|
mem_usage_percent : mem_measurement.rss().get::<units::information::megabyte>() as f64 / total_mem as f64 * 100_f64,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else if cfg!(target_os = "macos") {
|
||||||
|
// macOS
|
||||||
|
dbg!("Mac"); // TODO: Remove
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
dbg!("Else"); // TODO: Remove
|
||||||
|
}
|
||||||
|
|
||||||
Ok(process_vector)
|
Ok(process_vector)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sort_processes(process_vector : &mut Vec<ProcessData>, sorting_method : &ProcessSorting, reverse_order : bool) {
|
pub fn sort_processes(process_vector : &mut Vec<ProcessData>, sorting_method : &ProcessSorting, reverse_order : bool) {
|
||||||
match sorting_method {
|
match sorting_method {
|
||||||
ProcessSorting::CPU => process_vector.sort_by(|a, b| get_ordering(a.cpu_usage_percent, b.cpu_usage_percent, reverse_order)),
|
// Always sort alphabetically first!
|
||||||
ProcessSorting::MEM => process_vector.sort_by(|a, b| get_ordering(a.mem_usage_in_mb, b.mem_usage_in_mb, reverse_order)),
|
ProcessSorting::CPU => {
|
||||||
ProcessSorting::PID => process_vector.sort_by(|a, b| get_ordering(a.pid, b.pid, reverse_order)),
|
process_vector.sort_by(|a, b| get_ordering(&a.command, &b.command, false));
|
||||||
|
process_vector.sort_by(|a, b| get_ordering(a.cpu_usage_percent, b.cpu_usage_percent, reverse_order));
|
||||||
|
}
|
||||||
|
ProcessSorting::MEM => {
|
||||||
|
process_vector.sort_by(|a, b| get_ordering(&a.command, &b.command, false));
|
||||||
|
process_vector.sort_by(|a, b| get_ordering(a.mem_usage_percent, b.mem_usage_percent, reverse_order));
|
||||||
|
}
|
||||||
|
ProcessSorting::PID => {
|
||||||
|
process_vector.sort_by(|a, b| get_ordering(&a.command, &b.command, false));
|
||||||
|
process_vector.sort_by(|a, b| get_ordering(a.pid, b.pid, reverse_order));
|
||||||
|
}
|
||||||
ProcessSorting::NAME => process_vector.sort_by(|a, b| get_ordering(&a.command, &b.command, reverse_order)),
|
ProcessSorting::NAME => process_vector.sort_by(|a, b| get_ordering(&a.command, &b.command, reverse_order)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user