From a614f44a9cfd76a70b61f7c8643a2e3075029afd Mon Sep 17 00:00:00 2001 From: Krysztal Huang Date: Sat, 8 Nov 2025 02:10:45 +0800 Subject: [PATCH] pgrep: migrate some field into `OnceLock` of `ProcessInformation` `ProcessInformation::cached_stat` -> `ProcessInformation::stat` `ProcessInformation::cached_status` -> `ProcessInformation::status` `ProcessInformation::cached_thread_ids` -> `ProcessInformation::thread_ids` --- src/uu/pgrep/src/process.rs | 63 ++++++++++++------------------------- src/uu/pidof/src/pidof.rs | 2 +- 2 files changed, 21 insertions(+), 44 deletions(-) diff --git a/src/uu/pgrep/src/process.rs b/src/uu/pgrep/src/process.rs index 724cc4d..7a150de 100644 --- a/src/uu/pgrep/src/process.rs +++ b/src/uu/pgrep/src/process.rs @@ -6,13 +6,12 @@ use regex::Regex; use std::fs::read_link; use std::hash::Hash; -use std::sync::LazyLock; +use std::sync::{LazyLock, OnceLock}; use std::{ collections::HashMap, fmt::{self, Display, Formatter}, fs, io, path::PathBuf, - rc::Rc, }; use walkdir::{DirEntry, WalkDir}; @@ -319,7 +318,7 @@ impl Namespace { } /// Process ID and its information -#[derive(Debug, Clone, Default, PartialEq, Eq)] +#[derive(Debug, Clone, Default)] pub struct ProcessInformation { pub pid: usize, pub cmdline: String, @@ -328,13 +327,13 @@ pub struct ProcessInformation { inner_stat: String, /// Processed `/proc/self/status` file - cached_status: Option>>, + status: OnceLock>, /// Processed `/proc/self/stat` file - cached_stat: Option>>, + stat: OnceLock>, cached_start_time: Option, - cached_thread_ids: Option>>, + thread_ids: OnceLock>, } impl ProcessInformation { @@ -402,34 +401,19 @@ impl ProcessInformation { } /// Collect information from `/proc//status` file - pub fn status(&mut self) -> Rc> { - if let Some(c) = &self.cached_status { - return Rc::clone(c); - } - - let result = self - .inner_status - .lines() - .filter_map(|it| it.split_once(':')) - .map(|it| (it.0.to_string(), it.1.trim_start().to_string())) - .collect::>(); - - let result = Rc::new(result); - self.cached_status = Some(Rc::clone(&result)); - Rc::clone(&result) + pub fn status(&self) -> &HashMap { + self.status.get_or_init(|| { + self.inner_status + .lines() + .filter_map(|it| it.split_once(':')) + .map(|it| (it.0.to_string(), it.1.trim_start().to_string())) + .collect::>() + }) } /// Collect information from `/proc//stat` file - pub fn stat(&mut self) -> Rc> { - if let Some(c) = &self.cached_stat { - return Rc::clone(c); - } - - let result: Vec<_> = stat_split(&self.inner_stat); - - let result = Rc::new(result); - self.cached_stat = Some(Rc::clone(&result)); - Rc::clone(&result) + pub fn stat(&self) -> &Vec { + self.stat.get_or_init(|| stat_split(&self.inner_stat)) } pub fn name(&mut self) -> Result { @@ -615,13 +599,9 @@ impl ProcessInformation { Teletype::Unknown } - pub fn thread_ids(&mut self) -> Rc> { - if let Some(c) = &self.cached_thread_ids { - return Rc::clone(c); - } - - let tids_dir = format!("/proc/{}/task", self.pid); - let result = Rc::new( + pub fn thread_ids(&mut self) -> &[usize] { + self.thread_ids.get_or_init(|| { + let tids_dir = format!("/proc/{}/task", self.pid); WalkDir::new(tids_dir) .min_depth(1) .max_depth(1) @@ -633,11 +613,8 @@ impl ProcessInformation { .file_name() .map(|it| it.to_str().unwrap().parse::().unwrap()) }) - .collect::>(), - ); - - self.cached_thread_ids = Some(Rc::clone(&result)); - Rc::clone(&result) + .collect::>() + }) } pub fn env_vars(&self) -> Result, io::Error> { diff --git a/src/uu/pidof/src/pidof.rs b/src/uu/pidof/src/pidof.rs index cf9e698..85d1f7e 100644 --- a/src/uu/pidof/src/pidof.rs +++ b/src/uu/pidof/src/pidof.rs @@ -122,7 +122,7 @@ fn collect_matched_pids(matches: &ArgMatches) -> Vec { } if matches.get_flag("t") { - processed.extend_from_slice(&process.thread_ids()); + processed.extend_from_slice(process.thread_ids()); } else { processed.push(process.pid); }