From 12cf33404a49cc9c2b189b99f9049fb1b85c306d Mon Sep 17 00:00:00 2001 From: dalance Date: Thu, 28 Jan 2021 20:31:10 +0900 Subject: [PATCH] Add thread information #30 --- CHANGELOG.md | 2 + README.md | 28 +++++---- src/columns/command.rs | 4 +- src/columns/cpu_time.rs | 2 +- src/columns/eip.rs | 2 +- src/columns/esp.rs | 2 +- src/columns/maj_flt.rs | 2 +- src/columns/min_flt.rs | 2 +- src/columns/nice.rs | 2 +- src/columns/pid.rs | 17 +++++ src/columns/policy.rs | 2 +- src/columns/priority.rs | 2 +- src/columns/processor.rs | 4 +- src/columns/rt_priority.rs | 4 +- src/columns/start_time.rs | 2 +- src/columns/state.rs | 2 +- src/columns/threads.rs | 2 +- src/columns/tree.rs | 13 ++-- src/columns/tty.rs | 2 +- src/columns/usage_cpu.rs | 4 +- src/columns/usage_mem.rs | 2 +- src/columns/user.rs | 4 +- src/columns/vm_rss.rs | 2 +- src/columns/vm_size.rs | 2 +- src/config.rs | 6 ++ src/main.rs | 4 ++ src/process/linux.rs | 125 +++++++++++++++++++++++++++++++++++-- src/process/macos.rs | 2 +- src/process/windows.rs | 2 +- src/view.rs | 10 ++- 30 files changed, 209 insertions(+), 50 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08c43569a..0243482ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## [Unreleased](https://github.com/dalance/procs/compare/v0.11.0...Unreleased) - ReleaseDate +* [Added] thread information [#30](https://github.com/dalance/procs/issues/30) + ## [v0.11.0](https://github.com/dalance/procs/compare/v0.10.10...v0.11.0) - 2021-01-28 * [Added] automatic theme detection [#78](https://github.com/dalance/procs/issues/78) diff --git a/README.md b/README.md index f8999a7c9..f7c0163bb 100644 --- a/README.md +++ b/README.md @@ -336,6 +336,8 @@ logic = "And" [display] show_self = false +show_thread = false +show_thread_in_tree = true cut_to_terminal = true cut_to_pager = false cut_to_pipe = false @@ -549,18 +551,20 @@ style = "223" # 223 for both theme `[display]` section defines option for output display. -| Key | Value | Default | Description | -| --------------- | --------------------- | ---------------- | ---------------------------------------------------------------------------- | -| show_self | true, false | false | Whether the self process ( `procs` ) is shown | -| cut_to_terminal | true, false | true | Whether output lines are truncated for output into terminal | -| cut_to_pager | true, false | false | Whether output lines are truncated for output into pager | -| cut_to_pipe | true, false | false | Whether output lines are truncated for output into pipe | -| color_mode | Auto, Always, Disable | Auto | The default behavior of output coloring without `--color` commandline option | -| separator | [String] | │ | String used as Separator | -| ascending | [String] | ▲ | Ascending sort indicator | -| descending | [String] | ▼ | Descending sort indicator | -| tree_symbols | [String; 5] | [│, ─, ┬, ├, └] | Symbols used by tree view | -| abbr_sid | true, false | true | Whether machine SID is abbreviated ( windows only ) | +| Key | Value | Default | Description | +| ------------------- | --------------------- | ---------------- | ---------------------------------------------------------------------------- | +| show_self | true, false | false | Whether the self process ( `procs` ) is shown | +| show_thread | true, false | false | Whether the thread information is shown ( Linux only ) | +| show_thread_in_tree | true, false | true | Whether the thread information is shown in tree mode ( Linux only ) | +| cut_to_terminal | true, false | true | Whether output lines are truncated for output into terminal | +| cut_to_pager | true, false | false | Whether output lines are truncated for output into pager | +| cut_to_pipe | true, false | false | Whether output lines are truncated for output into pipe | +| color_mode | Auto, Always, Disable | Auto | The default behavior of output coloring without `--color` commandline option | +| separator | [String] | │ | String used as Separator | +| ascending | [String] | ▲ | Ascending sort indicator | +| descending | [String] | ▼ | Descending sort indicator | +| tree_symbols | [String; 5] | [│, ─, ┬, ├, └] | Symbols used by tree view | +| abbr_sid | true, false | true | Whether machine SID is abbreviated ( Windows only ) | If `color_mode` is `Auto`, color is enabled for terminal and pager, disabled for pipe. diff --git a/src/columns/command.rs b/src/columns/command.rs index 500a62922..3ff140de0 100644 --- a/src/columns/command.rs +++ b/src/columns/command.rs @@ -42,10 +42,10 @@ impl Column for Command { cmd = cmd.replace("\n", " ").replace("\t", " "); cmd } else { - proc.curr_proc.stat.comm.clone() + proc.curr_proc.stat().comm.clone() } } else { - proc.curr_proc.stat.comm.clone() + proc.curr_proc.stat().comm.clone() }; let raw_content = fmt_content.clone(); diff --git a/src/columns/cpu_time.rs b/src/columns/cpu_time.rs index 9b858a2db..1e3bce776 100644 --- a/src/columns/cpu_time.rs +++ b/src/columns/cpu_time.rs @@ -28,7 +28,7 @@ impl CpuTime { #[cfg(target_os = "linux")] impl Column for CpuTime { fn add(&mut self, proc: &ProcessInfo) { - let time_sec = (proc.curr_proc.stat.utime + proc.curr_proc.stat.stime) + let time_sec = (proc.curr_proc.stat().utime + proc.curr_proc.stat().stime) / procfs::ticks_per_second().unwrap_or(100) as u64; let fmt_content = util::parse_time(time_sec); diff --git a/src/columns/eip.rs b/src/columns/eip.rs index 7e68f694c..d4ef51762 100644 --- a/src/columns/eip.rs +++ b/src/columns/eip.rs @@ -27,7 +27,7 @@ impl Eip { impl Column for Eip { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.kstkeip; + let raw_content = proc.curr_proc.stat().kstkeip; let fmt_content = format!("{:016x}", raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/esp.rs b/src/columns/esp.rs index 917db511e..ebcf009b7 100644 --- a/src/columns/esp.rs +++ b/src/columns/esp.rs @@ -27,7 +27,7 @@ impl Esp { impl Column for Esp { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.kstkesp; + let raw_content = proc.curr_proc.stat().kstkesp; let fmt_content = format!("{:016x}", raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/maj_flt.rs b/src/columns/maj_flt.rs index a2e2d6529..ccbc9b79c 100644 --- a/src/columns/maj_flt.rs +++ b/src/columns/maj_flt.rs @@ -28,7 +28,7 @@ impl MajFlt { #[cfg(target_os = "linux")] impl Column for MajFlt { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.majflt; + let raw_content = proc.curr_proc.stat().majflt; let fmt_content = format!("{}", raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/min_flt.rs b/src/columns/min_flt.rs index 99d908a5a..7894b7bb1 100644 --- a/src/columns/min_flt.rs +++ b/src/columns/min_flt.rs @@ -28,7 +28,7 @@ impl MinFlt { #[cfg(target_os = "linux")] impl Column for MinFlt { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.minflt; + let raw_content = proc.curr_proc.stat().minflt; let fmt_content = format!("{}", raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/nice.rs b/src/columns/nice.rs index e6c36d4eb..5cdc6dbee 100644 --- a/src/columns/nice.rs +++ b/src/columns/nice.rs @@ -28,7 +28,7 @@ impl Nice { #[cfg(target_os = "linux")] impl Column for Nice { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.nice; + let raw_content = proc.curr_proc.stat().nice; let fmt_content = format!("{}", raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/pid.rs b/src/columns/pid.rs index df5fb596b..c4efebcd2 100644 --- a/src/columns/pid.rs +++ b/src/columns/pid.rs @@ -25,6 +25,23 @@ impl Pid { } } +#[cfg(target_os = "linux")] +impl Column for Pid { + fn add(&mut self, proc: &ProcessInfo) { + let raw_content = proc.pid; + let fmt_content = match proc.curr_proc { + crate::process::ProcessTask::Process(_) => format!("{}", raw_content), + _ => format!("[{}]", raw_content), + }; + + self.fmt_contents.insert(proc.pid, fmt_content); + self.raw_contents.insert(proc.pid, raw_content); + } + + column_default!(i32); +} + +#[cfg(not(target_os = "linux"))] impl Column for Pid { fn add(&mut self, proc: &ProcessInfo) { let raw_content = proc.pid; diff --git a/src/columns/policy.rs b/src/columns/policy.rs index e26ad428d..046a75a6c 100644 --- a/src/columns/policy.rs +++ b/src/columns/policy.rs @@ -28,7 +28,7 @@ impl Policy { #[cfg(target_os = "linux")] impl Column for Policy { fn add(&mut self, proc: &ProcessInfo) { - let fmt_content = match proc.curr_proc.stat.policy.map(|x| x as i32) { + let fmt_content = match proc.curr_proc.stat().policy.map(|x| x as i32) { Some(libc::SCHED_BATCH) => String::from("B"), Some(libc::SCHED_FIFO) => String::from("FF"), Some(libc::SCHED_IDLE) => String::from("IDL"), diff --git a/src/columns/priority.rs b/src/columns/priority.rs index 843bf15fe..009b77f79 100644 --- a/src/columns/priority.rs +++ b/src/columns/priority.rs @@ -28,7 +28,7 @@ impl Priority { #[cfg(target_os = "linux")] impl Column for Priority { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.priority; + let raw_content = proc.curr_proc.stat().priority; let fmt_content = format!("{}", raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/processor.rs b/src/columns/processor.rs index b86130e62..7a826f09e 100644 --- a/src/columns/processor.rs +++ b/src/columns/processor.rs @@ -27,8 +27,8 @@ impl Processor { impl Column for Processor { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.processor.unwrap_or_default(); - let fmt_content = if let Some(p) = proc.curr_proc.stat.processor { + let raw_content = proc.curr_proc.stat().processor.unwrap_or_default(); + let fmt_content = if let Some(p) = proc.curr_proc.stat().processor { format!("{}", p) } else { String::from("") diff --git a/src/columns/rt_priority.rs b/src/columns/rt_priority.rs index c01481193..9c687d2c2 100644 --- a/src/columns/rt_priority.rs +++ b/src/columns/rt_priority.rs @@ -27,8 +27,8 @@ impl RtPriority { impl Column for RtPriority { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.rt_priority.unwrap_or_default(); - let fmt_content = if let Some(p) = proc.curr_proc.stat.rt_priority { + let raw_content = proc.curr_proc.stat().rt_priority.unwrap_or_default(); + let fmt_content = if let Some(p) = proc.curr_proc.stat().rt_priority { format!("{}", p) } else { String::from("") diff --git a/src/columns/start_time.rs b/src/columns/start_time.rs index 799ff92e6..6151e03c2 100644 --- a/src/columns/start_time.rs +++ b/src/columns/start_time.rs @@ -44,7 +44,7 @@ impl StartTime { #[cfg(target_os = "linux")] impl Column for StartTime { fn add(&mut self, proc: &ProcessInfo) { - let starttime = proc.curr_proc.stat.starttime; + let starttime = proc.curr_proc.stat().starttime; let seconds_since_boot = starttime as f32 / *TICKS_PER_SECOND as f32; let raw_content = self.boot_time + Duration::milliseconds((seconds_since_boot * 1000.0) as i64); diff --git a/src/columns/state.rs b/src/columns/state.rs index f50eeb60c..c43d9f4a6 100644 --- a/src/columns/state.rs +++ b/src/columns/state.rs @@ -28,7 +28,7 @@ impl State { #[cfg(target_os = "linux")] impl Column for State { fn add(&mut self, proc: &ProcessInfo) { - let fmt_content = format!("{}", proc.curr_proc.stat.state); + let fmt_content = format!("{}", proc.curr_proc.stat().state); let raw_content = fmt_content.clone(); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/threads.rs b/src/columns/threads.rs index 3b0163d5e..e905a6296 100644 --- a/src/columns/threads.rs +++ b/src/columns/threads.rs @@ -28,7 +28,7 @@ impl Threads { #[cfg(target_os = "linux")] impl Column for Threads { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.num_threads; + let raw_content = proc.curr_proc.stat().num_threads; let fmt_content = format!("{}", raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/tree.rs b/src/columns/tree.rs index 3f7aaaf5b..dd7141841 100644 --- a/src/columns/tree.rs +++ b/src/columns/tree.rs @@ -212,6 +212,7 @@ impl Column for Tree { #[cfg(target_os = "linux")] mod tests { use super::*; + use crate::process::ProcessTask; use procfs::process::Process; use std::time::Duration; @@ -228,8 +229,8 @@ mod tests { let p0 = ProcessInfo { pid: 0, ppid: 0, - curr_proc: Process::myself().unwrap(), - prev_proc: Process::myself().unwrap(), + curr_proc: ProcessTask::Process(Process::myself().unwrap()), + prev_proc: ProcessTask::Process(Process::myself().unwrap()), curr_io: None, prev_io: None, curr_status: None, @@ -239,8 +240,8 @@ mod tests { let p1 = ProcessInfo { pid: 1, ppid: 0, - curr_proc: Process::myself().unwrap(), - prev_proc: Process::myself().unwrap(), + curr_proc: ProcessTask::Process(Process::myself().unwrap()), + prev_proc: ProcessTask::Process(Process::myself().unwrap()), curr_io: None, prev_io: None, curr_status: None, @@ -250,8 +251,8 @@ mod tests { let p2 = ProcessInfo { pid: 2, ppid: 1, - curr_proc: Process::myself().unwrap(), - prev_proc: Process::myself().unwrap(), + curr_proc: ProcessTask::Process(Process::myself().unwrap()), + prev_proc: ProcessTask::Process(Process::myself().unwrap()), curr_io: None, prev_io: None, curr_status: None, diff --git a/src/columns/tty.rs b/src/columns/tty.rs index e7af5009c..d883fa80f 100644 --- a/src/columns/tty.rs +++ b/src/columns/tty.rs @@ -28,7 +28,7 @@ impl Tty { #[cfg(target_os = "linux")] impl Column for Tty { fn add(&mut self, proc: &ProcessInfo) { - let (major, minor) = proc.curr_proc.stat.tty_nr(); + let (major, minor) = proc.curr_proc.stat().tty_nr(); let fmt_content = if major == 136 { format!("pts/{}", minor) } else { diff --git a/src/columns/usage_cpu.rs b/src/columns/usage_cpu.rs index c4c2d60ff..1198cbc36 100644 --- a/src/columns/usage_cpu.rs +++ b/src/columns/usage_cpu.rs @@ -28,8 +28,8 @@ impl UsageCpu { #[cfg(target_os = "linux")] impl Column for UsageCpu { fn add(&mut self, proc: &ProcessInfo) { - let curr_time = proc.curr_proc.stat.utime + proc.curr_proc.stat.stime; - let prev_time = proc.prev_proc.stat.utime + proc.prev_proc.stat.stime; + let curr_time = proc.curr_proc.stat().utime + proc.curr_proc.stat().stime; + let prev_time = proc.prev_proc.stat().utime + proc.prev_proc.stat().stime; let usage_ms = (curr_time - prev_time) * 1000 / procfs::ticks_per_second().unwrap_or(100) as u64; let interval_ms = proc.interval.as_secs() * 1000 + u64::from(proc.interval.subsec_millis()); diff --git a/src/columns/usage_mem.rs b/src/columns/usage_mem.rs index eb4c65b31..75846f745 100644 --- a/src/columns/usage_mem.rs +++ b/src/columns/usage_mem.rs @@ -80,7 +80,7 @@ fn get_mem_total() -> u64 { #[cfg(target_os = "linux")] impl Column for UsageMem { fn add(&mut self, proc: &ProcessInfo) { - let usage = proc.curr_proc.stat.rss_bytes() as f64 * 100.0 / self.mem_total as f64; + let usage = proc.curr_proc.stat().rss_bytes() as f64 * 100.0 / self.mem_total as f64; let fmt_content = format!("{:.1}", usage); let raw_content = (usage * 1000.0) as u32; diff --git a/src/columns/user.rs b/src/columns/user.rs index aa32990d6..be8968f46 100644 --- a/src/columns/user.rs +++ b/src/columns/user.rs @@ -33,11 +33,11 @@ impl User { #[cfg(target_os = "linux")] impl Column for User { fn add(&mut self, proc: &ProcessInfo) { - let user = users::get_user_by_uid(proc.curr_proc.owner); + let user = users::get_user_by_uid(proc.curr_proc.owner()); let fmt_content = if let Some(user) = user { format!("{}", user.name().to_string_lossy()) } else { - format!("{}", proc.curr_proc.owner) + format!("{}", proc.curr_proc.owner()) }; let raw_content = fmt_content.clone(); diff --git a/src/columns/vm_rss.rs b/src/columns/vm_rss.rs index befa0c385..f0c10ff3e 100644 --- a/src/columns/vm_rss.rs +++ b/src/columns/vm_rss.rs @@ -29,7 +29,7 @@ impl VmRss { #[cfg(target_os = "linux")] impl Column for VmRss { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.rss_bytes() as u64; + let raw_content = proc.curr_proc.stat().rss_bytes() as u64; let fmt_content = bytify(raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/columns/vm_size.rs b/src/columns/vm_size.rs index 5c4988d54..17328f2cd 100644 --- a/src/columns/vm_size.rs +++ b/src/columns/vm_size.rs @@ -29,7 +29,7 @@ impl VmSize { #[cfg(target_os = "linux")] impl Column for VmSize { fn add(&mut self, proc: &ProcessInfo) { - let raw_content = proc.curr_proc.stat.vsize; + let raw_content = proc.curr_proc.stat().vsize; let fmt_content = bytify(raw_content); self.fmt_contents.insert(proc.pid, fmt_content); diff --git a/src/config.rs b/src/config.rs index 5144b8436..14767ec7e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -502,6 +502,10 @@ pub enum ConfigSearchLogic { pub struct ConfigDisplay { #[serde(default = "default_false")] pub show_self: bool, + #[serde(default = "default_false")] + pub show_thread: bool, + #[serde(default = "default_true")] + pub show_thread_in_tree: bool, #[serde(default = "default_true")] pub cut_to_terminal: bool, #[serde(default = "default_false")] @@ -528,6 +532,8 @@ impl Default for ConfigDisplay { fn default() -> Self { ConfigDisplay { show_self: false, + show_thread: false, + show_thread_in_tree: true, cut_to_terminal: true, cut_to_pager: false, cut_to_pipe: false, diff --git a/src/main.rs b/src/main.rs index ecaf585f1..faab8c115 100644 --- a/src/main.rs +++ b/src/main.rs @@ -77,6 +77,10 @@ pub struct Opt { #[structopt(short = "l", long = "list")] pub list: bool, + /// Show thread + #[structopt(long = "thread")] + pub thread: bool, + /// Tree view #[structopt(short = "t", long = "tree")] pub tree: bool, diff --git a/src/process/linux.rs b/src/process/linux.rs index 5c43fb1e6..5050f256b 100644 --- a/src/process/linux.rs +++ b/src/process/linux.rs @@ -1,26 +1,90 @@ -use procfs::process::{Io, Process, Status}; +use procfs::process::{FDInfo, Io, Process, Stat, Status, TasksIter}; +use procfs::{ProcError, ProcessCgroup}; +use std::collections::HashMap; use std::thread; use std::time::{Duration, Instant}; +pub enum ProcessTask { + Process(Process), + Task { stat: Stat, owner: u32 }, +} + +impl ProcessTask { + pub fn stat(&self) -> &Stat { + match self { + ProcessTask::Process(x) => &x.stat, + ProcessTask::Task { stat: x, owner: _ } => x, + } + } + + pub fn cmdline(&self) -> Result, ProcError> { + match self { + ProcessTask::Process(x) => x.cmdline(), + _ => Err(ProcError::Other("not supported".to_string())), + } + } + + pub fn cgroups(&self) -> Result, ProcError> { + match self { + ProcessTask::Process(x) => x.cgroups(), + _ => Err(ProcError::Other("not supported".to_string())), + } + } + + pub fn fd(&self) -> Result, ProcError> { + match self { + ProcessTask::Process(x) => x.fd(), + _ => Err(ProcError::Other("not supported".to_string())), + } + } + + pub fn loginuid(&self) -> Result { + match self { + ProcessTask::Process(x) => x.loginuid(), + _ => Err(ProcError::Other("not supported".to_string())), + } + } + + pub fn owner(&self) -> u32 { + match self { + ProcessTask::Process(x) => x.owner, + ProcessTask::Task { stat: _, owner: x } => *x, + } + } + + pub fn wchan(&self) -> Result { + match self { + ProcessTask::Process(x) => x.wchan(), + _ => Err(ProcError::Other("not supported".to_string())), + } + } +} + pub struct ProcessInfo { pub pid: i32, pub ppid: i32, - pub curr_proc: Process, - pub prev_proc: Process, + pub curr_proc: ProcessTask, + pub prev_proc: ProcessTask, pub curr_io: Option, pub prev_io: Option, pub curr_status: Option, pub interval: Duration, } -pub fn collect_proc(interval: Duration) -> Vec { +pub fn collect_proc(interval: Duration, with_thread: bool) -> Vec { let mut base_procs = Vec::new(); + let mut base_tasks = HashMap::new(); let mut ret = Vec::new(); if let Ok(all_proc) = procfs::process::all_processes() { for proc in all_proc { let io = proc.io().ok(); let time = Instant::now(); + if with_thread { + if let Ok(iter) = proc.tasks() { + collect_task(iter, &mut base_tasks); + } + } base_procs.push((proc.pid(), proc, io, time)); } } @@ -38,6 +102,17 @@ pub fn collect_proc(interval: Duration) -> Vec { let curr_time = Instant::now(); let interval = curr_time - prev_time; let ppid = curr_proc.stat.ppid; + let owner = curr_proc.owner; + + let mut curr_tasks = HashMap::new(); + if with_thread { + if let Ok(iter) = curr_proc.tasks() { + collect_task(iter, &mut curr_tasks); + } + } + + let curr_proc = ProcessTask::Process(curr_proc); + let prev_proc = ProcessTask::Process(prev_proc); let proc = ProcessInfo { pid, @@ -51,7 +126,49 @@ pub fn collect_proc(interval: Duration) -> Vec { }; ret.push(proc); + + for (tid, (pid, curr_stat, curr_status, curr_io)) in curr_tasks { + if let Some((_, prev_stat, _, prev_io)) = base_tasks.remove(&tid) { + let proc = ProcessInfo { + pid: tid, + ppid: pid, + curr_proc: ProcessTask::Task { + stat: curr_stat, + owner, + }, + prev_proc: ProcessTask::Task { + stat: prev_stat, + owner, + }, + curr_io, + prev_io, + curr_status, + interval, + }; + ret.push(proc); + } + } } ret } + +fn collect_task(iter: TasksIter, map: &mut HashMap, Option)>) { + for task in iter { + let task = if let Ok(x) = task { + x + } else { + continue; + }; + if task.tid != task.pid { + let stat = if let Ok(x) = task.stat() { + x + } else { + continue; + }; + let status = task.status().ok(); + let io = task.io().ok(); + map.insert(task.tid, (task.pid, stat, status, io)); + } + } +} diff --git a/src/process/macos.rs b/src/process/macos.rs index 1c20143e7..d9d5b40c7 100644 --- a/src/process/macos.rs +++ b/src/process/macos.rs @@ -26,7 +26,7 @@ pub struct ProcessInfo { } #[cfg_attr(tarpaulin, skip)] -pub fn collect_proc(interval: Duration) -> Vec { +pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec { let mut base_procs = Vec::new(); let mut ret = Vec::new(); let arg_max = get_arg_max(); diff --git a/src/process/windows.rs b/src/process/windows.rs index 0283dd364..a0501f5f5 100644 --- a/src/process/windows.rs +++ b/src/process/windows.rs @@ -70,7 +70,7 @@ pub struct CpuInfo { } #[cfg_attr(tarpaulin, skip)] -pub fn collect_proc(interval: Duration) -> Vec { +pub fn collect_proc(interval: Duration, _with_thread: bool) -> Vec { let mut base_procs = Vec::new(); let mut ret = Vec::new(); diff --git a/src/view.rs b/src/view.rs index fc887fe7e..b7b627bfb 100644 --- a/src/view.rs +++ b/src/view.rs @@ -109,7 +109,15 @@ impl View { } } - let proc = collect_proc(Duration::from_millis(opt.interval)); + let show_thread = if opt.thread { + true + } else if opt.tree { + config.display.show_thread_in_tree + } else { + config.display.show_thread + }; + + let proc = collect_proc(Duration::from_millis(opt.interval), show_thread); for c in columns.iter_mut() { for p in &proc { c.column.add(&p);