feature: Add appox. total mem as an option for processes and basic mem

Adds a way to display the memory value as a column in the processes widget and the basic memory widget, rather than just the percentage.
This commit is contained in:
Clement Tsang 2020-08-17 12:41:37 -07:00 committed by GitHub
parent 59ce90f577
commit 3c373d7129
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 226 additions and 70 deletions

View file

@ -20,6 +20,7 @@
"haase",
"heim",
"hjkl",
"libc",
"markdownlint",
"minwindef",
"noheader",
@ -32,6 +33,7 @@
"softirq",
"stime",
"subwidget",
"sysconf",
"sysinfo",
"tokei",
"twrite",
@ -39,6 +41,7 @@
"use",
"use curr usage",
"utime",
"virt",
"whitespaces",
"winapi",
"winnt",

View file

@ -41,8 +41,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Features
- [#114](https://github.com/ClementTsang/bottom/pull/114): Show process state per process (originally in 0.4.0, moved to later). This only
shows if the processes are not merged together; I couldn't think of a nice way to show it when grouped together, unfortunately.
- [#114](https://github.com/ClementTsang/bottom/pull/114): Show process state per process (originally in 0.4.0, moved to later). This only shows if the processes are not merged together; I couldn't think of a nice way to show it when grouped together, unfortunately.
- Add (estimated) memory usage values, toggle this from percent to values for processes with `%`.
### Changes

4
Cargo.lock generated
View file

@ -762,9 +762,9 @@ checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
[[package]]
name = "libc"
version = "0.2.70"
version = "0.2.74"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
checksum = "a2f02823cf78b754822df5f7f268fb59822e7296276d3e069d8e8cb26a14bd10"
[[package]]
name = "lock_api"

View file

@ -38,6 +38,7 @@ backtrace = "0.3"
serde = {version = "1.0", features = ["derive"] }
unicode-segmentation = "1.6.0"
unicode-width = "0.1.7"
# libc = "0.2.74"
# tui = {version = "0.10.0", features = ["crossterm"], default-features = false, git = "https://github.com/fdehau/tui-rs.git"}
tui = {version = "0.9.5", features = ["crossterm"], default-features = false }

View file

@ -225,6 +225,7 @@ Run using `btm`.
| `P` | Toggle between showing the full path or just the process name |
| `s, F6` | Open process sort widget |
| `I` | Invert current sort |
| `%` | Toggle between values and percentages for memory usage |
#### Process search bindings
@ -260,6 +261,12 @@ Run using `btm`.
| `Left, Alt-h` | Go to the next battery |
| `Right, Alt-l` | Go to the previous battery |
#### Basic memory bindings
| | |
| --- | ------------------------------------------------------ |
| `%` | Toggle between values and percentages for memory usage |
### Process searching keywords
- Note none of the keywords are case sensitive.

View file

@ -80,6 +80,9 @@ pub struct App {
#[builder(default = false, setter(skip))]
pub is_force_redraw: bool,
#[builder(default = false, setter(skip))]
pub basic_mode_use_percent: bool,
pub cpu_state: CpuState,
pub mem_state: MemState,
pub net_state: NetState,
@ -342,6 +345,30 @@ impl App {
}
}
pub fn toggle_percentages(&mut self) {
match &self.current_widget.widget_type {
BottomWidgetType::BasicMem => {
self.basic_mode_use_percent = !self.basic_mode_use_percent; // Oh god this is so lazy.
}
BottomWidgetType::Proc => {
if let Some(proc_widget_state) = self
.proc_state
.widget_states
.get_mut(&self.current_widget.widget_id)
{
proc_widget_state
.columns
.toggle(&processes::ProcessSorting::Mem);
proc_widget_state
.columns
.toggle(&processes::ProcessSorting::MemPercent);
self.proc_state.force_update = Some(self.current_widget.widget_id);
}
}
_ => {}
}
}
pub fn toggle_ignore_case(&mut self) {
let is_in_search_widget = self.is_in_search_widget();
if let Some(proc_widget_state) = self
@ -1111,6 +1138,7 @@ impl App {
'e' => self.expand_widget(),
's' => self.toggle_sort(),
'I' => self.invert_sort(),
'%' => self.toggle_percentages(),
_ => {}
}

View file

@ -87,6 +87,7 @@ pub struct DataCollector {
widgets_to_harvest: UsedWidgets,
battery_manager: Option<Manager>,
battery_list: Option<Vec<Battery>>,
// page_file_size_kb: u64,
}
impl Default for DataCollector {
@ -110,6 +111,11 @@ impl Default for DataCollector {
widgets_to_harvest: UsedWidgets::default(),
battery_manager: None,
battery_list: None,
// page_file_size_kb: if cfg!(target_os = "linux") {
// unsafe { libc::sysconf(libc::_SC_PAGESIZE) as u64 / 1024 }
// } else {
// 0
// },
}
}
}
@ -200,6 +206,7 @@ impl DataCollector {
current_instant
.duration_since(self.last_collection_time)
.as_secs(),
self.mem_total_kb,
)
}
#[cfg(not(target_os = "linux"))]

View file

@ -53,8 +53,8 @@ pub async fn get_network_data(
(0, 0)
} else {
(
((total_rx - *prev_net_rx) as f64 / elapsed_time) as u64,
((total_tx - *prev_net_tx) as f64 / elapsed_time) as u64,
((total_rx.saturating_sub(*prev_net_rx)) as f64 / elapsed_time) as u64,
((total_tx.saturating_sub(*prev_net_tx)) as f64 / elapsed_time) as u64,
)
};

View file

@ -62,6 +62,9 @@ pub struct ProcessHarvest {
pub pid: u32,
pub cpu_usage_percent: f64,
pub mem_usage_percent: f64,
pub mem_usage_kb: u64,
// pub rss_kb: u64,
// pub virt_kb: u64,
pub name: String,
pub path: String,
pub read_bytes_per_sec: u64,
@ -224,12 +227,13 @@ fn get_linux_cpu_usage(
}
}
#[allow(clippy::too_many_arguments)]
#[cfg(target_os = "linux")]
fn convert_ps<S: core::hash::BuildHasher>(
process: &str, cpu_usage: f64, cpu_fraction: f64,
prev_pid_stats: &mut HashMap<u32, PrevProcDetails, S>,
new_pid_stats: &mut HashMap<u32, PrevProcDetails, S>, use_current_cpu_total: bool,
time_difference_in_secs: u64,
time_difference_in_secs: u64, mem_total_kb: u64,
) -> std::io::Result<ProcessHarvest> {
let pid = (&process[..10])
.trim()
@ -313,6 +317,7 @@ fn convert_ps<S: core::hash::BuildHasher>(
name,
path,
mem_usage_percent,
mem_usage_kb: (mem_usage_percent * mem_total_kb as f64 / 100.0) as u64,
cpu_usage_percent,
total_read_bytes,
total_write_bytes,
@ -327,7 +332,7 @@ fn convert_ps<S: core::hash::BuildHasher>(
pub fn linux_get_processes_list(
prev_idle: &mut f64, prev_non_idle: &mut f64,
prev_pid_stats: &mut HashMap<u32, PrevProcDetails, RandomState>, use_current_cpu_total: bool,
time_difference_in_secs: u64,
time_difference_in_secs: u64, mem_total_kb: u64,
) -> crate::utils::error::Result<Vec<ProcessHarvest>> {
let ps_result = Command::new("ps")
.args(&["-axo", "pid:10,comm:100,%mem:5,args:100", "--noheader"])
@ -336,7 +341,6 @@ pub fn linux_get_processes_list(
let split_string = ps_stdout.split('\n');
if let Ok((cpu_usage, cpu_fraction)) = cpu_usage_calculation(prev_idle, prev_non_idle) {
let process_list = split_string.collect::<Vec<&str>>();
let mut new_pid_stats = HashMap::new();
let process_vector: Vec<ProcessHarvest> = process_list
@ -352,6 +356,7 @@ pub fn linux_get_processes_list(
&mut new_pid_stats,
use_current_cpu_total,
time_difference_in_secs,
mem_total_kb,
) {
if !process_object.name.is_empty() {
Some(process_object)
@ -431,6 +436,7 @@ pub fn windows_macos_get_processes_list(
} else {
0.0
},
mem_usage_kb: process_val.memory(),
cpu_usage_percent: process_cpu_usage,
read_bytes_per_sec: disk_usage.read_bytes,
write_bytes_per_sec: disk_usage.written_bytes,

View file

@ -671,12 +671,12 @@ impl Prefix {
match prefix_type {
PrefixType::Cpu => matches_condition(
&numerical_query.condition,
process.cpu_usage,
process.cpu_percent_usage,
numerical_query.value,
),
PrefixType::Mem => matches_condition(
&numerical_query.condition,
process.mem_usage,
process.mem_percent_usage,
numerical_query.value,
),
PrefixType::Rps => matches_condition(

View file

@ -165,6 +165,7 @@ impl Default for ProcColumn {
ProcessName,
Command,
CpuPercent,
Mem,
MemPercent,
ReadPerSecond,
WritePerSecond,
@ -187,7 +188,7 @@ impl Default for ProcColumn {
},
);
}
MemPercent | Mem => {
MemPercent => {
column_mapping.insert(
column,
ColumnInfo {
@ -196,6 +197,15 @@ impl Default for ProcColumn {
},
);
}
Mem => {
column_mapping.insert(
column,
ColumnInfo {
enabled: false,
shortcut: Some("m"),
},
);
}
ProcessName => {
column_mapping.insert(
column,
@ -250,6 +260,20 @@ impl Default for ProcColumn {
}
impl ProcColumn {
pub fn toggle(&mut self, column: &ProcessSorting) {
if let Some(mapping) = self.column_mapping.get_mut(column) {
mapping.enabled = !(mapping.enabled);
}
}
pub fn is_enabled(&self, column: &ProcessSorting) -> bool {
if let Some(mapping) = self.column_mapping.get(column) {
mapping.enabled
} else {
false
}
}
pub fn get_enabled_columns_len(&self) -> usize {
self.ordered_columns
.iter()

View file

@ -42,8 +42,10 @@ pub struct DisplayableData {
pub process_data: Vec<ConvertedProcessData>,
// What's actually displayed
pub finalized_process_data_map: HashMap<u64, Vec<ConvertedProcessData>>,
pub mem_label: String,
pub swap_label: String,
pub mem_label_percent: String,
pub swap_label_percent: String,
pub mem_label_frac: String,
pub swap_label_frac: String,
pub mem_data: Vec<(f64, f64)>,
pub swap_data: Vec<(f64, f64)>,
pub cpu_data: Vec<ConvertedCpuData>,

View file

@ -76,7 +76,7 @@ impl HelpDialog for Painter {
app_state.help_dialog_state.scroll_state.max_scroll_index =
(self.styled_help_text.len() as u16
+ (constants::HELP_TEXT.len() as u16 - 4)
+ (constants::HELP_TEXT.len() as u16 - 5)
+ overflow_buffer)
.saturating_sub(draw_loc.height);

View file

@ -67,6 +67,7 @@ impl DiskTableWidget for Painter {
get_variable_intrinsic_widths(width as u16, &width_ratios, &DISK_HEADERS_LENS);
let intrinsic_widths = &variable_intrinsic_results.0[0..variable_intrinsic_results.1];
// TODO: This seems to be bugged? The selected text style gets "stuck"? I think this gets fixed with tui 0.10?
let (border_and_title_style, highlight_style) = if is_on_widget {
(
self.colours.highlighted_border_style,

View file

@ -38,8 +38,6 @@ impl MemBasicWidget for Painter {
);
}
// +9 due to 3 + 4 + 2 + 2 columns for the name & space + percentage + bar bounds + margin spacing
let bar_length = usize::from(draw_loc.width.saturating_sub(11));
let ram_use_percentage = if let Some(mem) = mem_data.last() {
mem.1
} else {
@ -50,21 +48,64 @@ impl MemBasicWidget for Painter {
} else {
0.0
};
let num_bars_ram = calculate_basic_use_bars(ram_use_percentage, bar_length);
let num_bars_swap = calculate_basic_use_bars(swap_use_percentage, bar_length);
let mem_label = format!(
"RAM[{}{}{:3.0}%]\n",
"|".repeat(num_bars_ram),
" ".repeat(bar_length - num_bars_ram),
ram_use_percentage.round(),
// +7 due to 3 + 2 + 2 columns for the name & space + bar bounds + margin spacing
// Then + length of fraction
let ram_bar_length = usize::from(
draw_loc
.width
.saturating_sub(7)
.saturating_sub(app_state.canvas_data.mem_label_frac.trim().len() as u16),
);
let swap_label = format!(
"SWP[{}{}{:3.0}%]",
"|".repeat(num_bars_swap),
" ".repeat(bar_length - num_bars_swap),
swap_use_percentage.round(),
let swap_bar_length = usize::from(
draw_loc
.width
.saturating_sub(7)
.saturating_sub(app_state.canvas_data.swap_label_frac.trim().len() as u16),
);
let num_bars_ram = calculate_basic_use_bars(ram_use_percentage, ram_bar_length);
let num_bars_swap = calculate_basic_use_bars(swap_use_percentage, swap_bar_length);
// TODO: Use different styling for the frac.
let mem_label = if app_state.basic_mode_use_percent {
format!(
"RAM[{}{}{:3.0}%]\n",
"|".repeat(num_bars_ram),
" ".repeat(
ram_bar_length - num_bars_ram
+ app_state.canvas_data.mem_label_frac.trim().len()
- 4
),
ram_use_percentage.round()
)
} else {
format!(
"RAM[{}{}{}]\n",
"|".repeat(num_bars_ram),
" ".repeat(ram_bar_length - num_bars_ram),
&app_state.canvas_data.mem_label_frac.trim()
)
};
let swap_label = if app_state.basic_mode_use_percent {
format!(
"SWP[{}{}{:3.0}%]",
"|".repeat(num_bars_swap),
" ".repeat(
swap_bar_length - num_bars_swap
+ app_state.canvas_data.swap_label_frac.trim().len()
- 4
),
swap_use_percentage.round()
)
} else {
format!(
"SWP[{}{}{}]",
"|".repeat(num_bars_swap),
" ".repeat(swap_bar_length - num_bars_swap),
&app_state.canvas_data.swap_label_frac.trim()
)
};
let mem_text = [
Text::styled(mem_label, self.colours.ram_style),
Text::styled(swap_label, self.colours.swap_style),

View file

@ -62,10 +62,13 @@ impl MemGraphWidget for Painter {
.labels_style(self.colours.graph_style);
let mut mem_canvas_vec: Vec<Dataset<'_>> = vec![];
let mem_label = format!(
"RAM:{}{}",
app_state.canvas_data.mem_label_percent, app_state.canvas_data.mem_label_frac
);
mem_canvas_vec.push(
Dataset::default()
.name(&app_state.canvas_data.mem_label)
.name(&mem_label)
.marker(if app_state.app_config_fields.use_dot {
Marker::Dot
} else {
@ -76,9 +79,13 @@ impl MemGraphWidget for Painter {
.graph_type(tui::widgets::GraphType::Line),
);
let swap_label = format!(
"SWP:{}{}",
app_state.canvas_data.swap_label_percent, app_state.canvas_data.swap_label_frac
);
mem_canvas_vec.push(
Dataset::default()
.name(&app_state.canvas_data.swap_label)
.name(&swap_label)
.marker(if app_state.app_config_fields.use_dot {
Marker::Dot
} else {

View file

@ -1,5 +1,5 @@
use crate::{
app::App,
app::{data_harvester::processes::ProcessSorting, App},
canvas::{
drawing_utils::{
get_search_start_position, get_start_position, get_variable_intrinsic_widths,
@ -152,6 +152,7 @@ impl ProcessTableWidget for Painter {
// Draw!
let is_proc_widget_grouped = proc_widget_state.is_grouped;
let mem_enabled = proc_widget_state.columns.is_enabled(&ProcessSorting::Mem);
let process_rows = sliced_vec.iter().map(|process| {
Row::Data(
vec![
@ -161,8 +162,12 @@ impl ProcessTableWidget for Painter {
process.pid.to_string()
},
process.name.clone(),
format!("{:.1}%", process.cpu_usage),
format!("{:.1}%", process.mem_usage),
format!("{:.1}%", process.cpu_percent_usage),
if mem_enabled {
format!("{:.0}{}", process.mem_usage_str.0, process.mem_usage_str.1)
} else {
format!("{:.1}%", process.mem_percent_usage)
},
process.read_per_sec.to_string(),
process.write_per_sec.to_string(),
process.total_read.to_string(),

View file

@ -42,14 +42,15 @@ lazy_static! {
}
// Help text
pub const HELP_CONTENTS_TEXT: [&str; 7] = [
pub const HELP_CONTENTS_TEXT: [&str; 8] = [
"Press the corresponding numbers to jump to the section, or scroll:\n",
"1 - General\n",
"2 - CPU widget\n",
"3 - Process widget\n",
"4 - Process search widget\n",
"5 - Process sort widget\n",
"6 - Battery widget",
"6 - Battery widget\n",
"7 - Basic memory widget",
];
pub const GENERAL_HELP_TEXT: [&str; 29] = [
@ -91,7 +92,7 @@ pub const CPU_HELP_TEXT: [&str; 2] = [
// TODO [Help]: Search in help?
// TODO [Help]: Move to using tables for easier formatting?
pub const PROCESS_HELP_TEXT: [&str; 11] = [
pub const PROCESS_HELP_TEXT: [&str; 12] = [
"3 - Process widget\n",
"dd Kill the selected process\n",
"c Sort by CPU usage, press again to reverse sorting order\n",
@ -102,7 +103,8 @@ pub const PROCESS_HELP_TEXT: [&str; 11] = [
"Ctrl-f, / Open process search widget\n",
"P Toggle between showing the full path or just the process name\n",
"s, F6 Open process sort widget\n",
"I Invert current sort",
"I Invert current sort\n",
"% Toggle between values and percentages for memory usage",
];
pub const SEARCH_HELP_TEXT: [&str; 43] = [
@ -166,6 +168,11 @@ pub const BATTERY_HELP_TEXT: [&str; 3] = [
"Right Go to next battery",
];
pub const BASIC_MEM_HELP_TEXT: [&str; 2] = [
"7 - Basic memory widget\n",
"% Toggle between values and percentages for memory usage",
];
lazy_static! {
pub static ref HELP_TEXT: Vec<Vec<&'static str>> = vec![
HELP_CONTENTS_TEXT.to_vec(),
@ -175,6 +182,7 @@ lazy_static! {
SEARCH_HELP_TEXT.to_vec(),
SORT_HELP_TEXT.to_vec(),
BATTERY_HELP_TEXT.to_vec(),
BASIC_MEM_HELP_TEXT.to_vec(),
];
}

View file

@ -34,8 +34,10 @@ pub struct ConvertedNetworkData {
pub struct ConvertedProcessData {
pub pid: u32,
pub name: String,
pub cpu_usage: f64,
pub mem_usage: f64,
pub cpu_percent_usage: f64,
pub mem_percent_usage: f64,
pub mem_usage_kb: u64,
pub mem_usage_str: (f64, String),
pub group_pids: Vec<u32>,
pub read_per_sec: String,
pub write_per_sec: String,
@ -51,8 +53,9 @@ pub struct ConvertedProcessData {
#[derive(Clone, Default, Debug)]
pub struct SingleProcessData {
pub pid: u32,
pub cpu_usage: f64,
pub mem_usage: f64,
pub cpu_percent_usage: f64,
pub mem_percent_usage: f64,
pub mem_usage_kb: u64,
pub group_pids: Vec<u32>,
pub read_per_sec: u64,
pub write_per_sec: u64,
@ -231,9 +234,11 @@ pub fn convert_swap_data_points(
result
}
pub fn convert_mem_labels(current_data: &data_farmer::DataCollection) -> (String, String) {
let mem_label = "RAM:".to_string()
+ &format!(
pub fn convert_mem_labels(
current_data: &data_farmer::DataCollection,
) -> (String, String, String, String) {
(
format!(
"{:3.0}%",
match current_data.memory_harvest.mem_total_in_mb {
0 => 0.0,
@ -241,15 +246,13 @@ pub fn convert_mem_labels(current_data: &data_farmer::DataCollection) -> (String
current_data.memory_harvest.mem_used_in_mb as f64 * 100.0
/ current_data.memory_harvest.mem_total_in_mb as f64,
}
)
+ &format!(
),
format!(
" {:.1}GB/{:.1}GB",
current_data.memory_harvest.mem_used_in_mb as f64 / 1024.0,
(current_data.memory_harvest.mem_total_in_mb as f64 / 1024.0)
);
let swap_label = "SWP:".to_string()
+ &format!(
),
format!(
"{:3.0}%",
match current_data.swap_harvest.mem_total_in_mb {
0 => 0.0,
@ -257,14 +260,13 @@ pub fn convert_mem_labels(current_data: &data_farmer::DataCollection) -> (String
current_data.swap_harvest.mem_used_in_mb as f64 * 100.0
/ current_data.swap_harvest.mem_total_in_mb as f64,
}
)
+ &format!(
),
format!(
" {:.1}GB/{:.1}GB",
current_data.swap_harvest.mem_used_in_mb as f64 / 1024.0,
(current_data.swap_harvest.mem_total_in_mb as f64 / 1024.0)
);
(mem_label, swap_label)
),
)
}
pub fn get_rx_tx_data_points(
@ -398,8 +400,10 @@ pub fn convert_process_data(
ProcessNamingType::Name => process.name.to_string(),
ProcessNamingType::Path => process.path.to_string(),
},
cpu_usage: process.cpu_usage_percent,
mem_usage: process.mem_usage_percent,
cpu_percent_usage: process.cpu_usage_percent,
mem_percent_usage: process.mem_usage_percent,
mem_usage_kb: process.mem_usage_kb,
mem_usage_str: get_exact_byte_values(process.mem_usage_kb * 1024, false),
group_pids: vec![process.pid],
read_per_sec,
write_per_sec,
@ -428,8 +432,9 @@ pub fn convert_process_data(
..SingleProcessData::default()
});
(*entry).cpu_usage += process.cpu_usage_percent;
(*entry).mem_usage += process.mem_usage_percent;
(*entry).cpu_percent_usage += process.cpu_usage_percent;
(*entry).mem_percent_usage += process.mem_usage_percent;
(*entry).mem_usage_kb += process.mem_usage_kb;
(*entry).group_pids.push(process.pid);
(*entry).read_per_sec += process.read_bytes_per_sec;
(*entry).write_per_sec += process.write_bytes_per_sec;
@ -458,8 +463,10 @@ pub fn convert_process_data(
ConvertedProcessData {
pid: p.pid,
name: identifier.to_string(),
cpu_usage: p.cpu_usage,
mem_usage: p.mem_usage,
cpu_percent_usage: p.cpu_percent_usage,
mem_percent_usage: p.mem_percent_usage,
mem_usage_kb: p.mem_usage_kb,
mem_usage_str: get_exact_byte_values(p.mem_usage_kb * 1024, false),
group_pids: p.group_pids,
read_per_sec,
write_per_sec,

View file

@ -213,8 +213,10 @@ fn main() -> error::Result<()> {
app.canvas_data.swap_data =
convert_swap_data_points(&app.data_collection, false);
let memory_and_swap_labels = convert_mem_labels(&app.data_collection);
app.canvas_data.mem_label = memory_and_swap_labels.0;
app.canvas_data.swap_label = memory_and_swap_labels.1;
app.canvas_data.mem_label_percent = memory_and_swap_labels.0;
app.canvas_data.mem_label_frac = memory_and_swap_labels.1;
app.canvas_data.swap_label_percent = memory_and_swap_labels.2;
app.canvas_data.swap_label_frac = memory_and_swap_labels.3;
}
if app.used_widgets.use_cpu {
@ -668,20 +670,26 @@ fn sort_process_data(
ProcessSorting::CpuPercent => {
to_sort_vec.sort_by(|a, b| {
utils::gen_util::get_ordering(
a.cpu_usage,
b.cpu_usage,
a.cpu_percent_usage,
b.cpu_percent_usage,
proc_widget_state.process_sorting_reverse,
)
});
}
ProcessSorting::Mem => {
// TODO: Do when I do mem values in processes
to_sort_vec.sort_by(|a, b| {
utils::gen_util::get_ordering(
a.mem_usage_kb,
b.mem_usage_kb,
proc_widget_state.process_sorting_reverse,
)
});
}
ProcessSorting::MemPercent => {
to_sort_vec.sort_by(|a, b| {
utils::gen_util::get_ordering(
a.mem_usage,
b.mem_usage,
a.mem_percent_usage,
b.mem_percent_usage,
proc_widget_state.process_sorting_reverse,
)
});