Skip to content

Commit

Permalink
WIP rss take 2, not working
Browse files Browse the repository at this point in the history
  • Loading branch information
Lars T Hansen committed Jan 15, 2024
1 parent d23ae07 commit 69eb02e
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 8 deletions.
5 changes: 4 additions & 1 deletion src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,12 @@ pub fn get_process_information() -> Result<Vec<Process>, CmdError> {
// `cputimes` is unaffected by `--cumulative`.
//
// The format of `bsdtime` is `m...m:ss` in minutes and seconds.
//
// We get the `drs` field because it corresponds most closely to the RssAnon value extracted by
// procfs.rs.

const PS_COMMAND: &str =
"ps -e --no-header --cumulative -o pid,uid,user:22,pcpu,pmem,bsdtime,size,rss,ppid,sess,comm";
"ps -e --no-header --cumulative -o pid,uid,user:22,pcpu,pmem,bsdtime,size,drs,ppid,sess,comm";

fn parse_ps_output(raw_text: &str) -> Vec<Process> {
raw_text
Expand Down
40 changes: 33 additions & 7 deletions src/procfs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,39 @@ pub fn get_process_information(fs: &dyn procfsapi::ProcfsAPI, memtotal_kib: usiz
// field.

let size_kib;
let rss_kib;
if let Ok(s) = fs.read_to_string(&format!("{pid}/statm")) {
let fields = s.split_ascii_whitespace().collect::<Vec<&str>>();
rss_kib = parse_usize_field(&fields, 1, &s, "statm", pid, "resident set size")?
* kib_per_page;
size_kib = parse_usize_field(&fields, 5, &s, "statm", pid, "data size")? * kib_per_page;
} else {
// This is *usually* benign - see above.
continue;
}

// The best value for resident memory is probably RssAnon of /proc/{pid}/status, which
// corresponds to "private data". It does not include text or file mappings, though these
// actually also take up real memory. But text can be shared, which matters both when we
// roll up processes and when the program is executing multiple times on the system, and
// file mappings, when they exist, are frequently read-only and evictable.
let mut rss_kib = 0;
if let Ok(status_info) = fs.read_to_string(&format!("{pid}/status")) {
for l in status_info.split('\n') {
if l.starts_with("RssAnon: ") {
// We expect "RssAnon:\s+(\d+)\s+kB", roughly
let fields = l.split_ascii_whitespace().collect::<Vec<&str>>();
if fields.len() != 3 || fields[2] != "kB" {
return Err(format!("Unexpected RssAnon in /proc/pid/statm: {l}"));
}
rss_kib = parse_usize_field(&fields, 1, &l, "status", pid, "private resident set size")?
* kib_per_page;
break;
}
}
}
if rss_kib == 0 {
// Again, usually benign.
continue;
}

// Now compute some derived quantities.

// pcpu and pmem are rounded to ##.#. We're going to get slightly different answers here
Expand Down Expand Up @@ -352,15 +374,19 @@ DirectMap1G: 11534336 kB
"4018/statm".to_string(),
"1255967 185959 54972 200 0 316078 0".to_string(),
);
files.insert(
"4081/status".to_string(),
"RssAnon: 12345 kB".to_string(),
);

let ticks_per_sec = 100.0; // We define this
let utime_ticks = 51361.0; // field(/proc/4018/stat, 14)
let stime_ticks = 15728.0; // field(/proc/4018/stat, 15)
let boot_time = 1698303295.0; // field(/proc/stat, "btime")
let start_ticks = 16400.0; // field(/proc/4018/stat, 22)
let rss: f64 = 185959.0 * 4.0; // pages_to_kib(field(/proc/4018/statm, 1))
let memtotal = 16093776.0; // field(/proc/meminfo, "MemTotal:")
let size = 316078 * 4; // pages_to_kib(field(/proc/4018/statm, 5))
let rss = 12345 * 4; // pages_to_kib(field(/proc/4018/status, "RssAnon:"))

// now = boot_time + start_time + utime_ticks + stime_ticks + arbitrary idle time
let now = (boot_time + (start_ticks / ticks_per_sec) + (utime_ticks / ticks_per_sec) + (stime_ticks / ticks_per_sec) + 2000.0) as u64;
Expand All @@ -385,11 +411,11 @@ DirectMap1G: 11534336 kB
let cpu_pct = (cpu_pct_value * 1000.0).round() / 10.0;
assert!(p.cpu_pct == cpu_pct);

let mem_pct = (rss * 1000.0 / memtotal).round() / 10.0;
assert!(p.mem_pct == mem_pct);
// let mem_pct = (rss * 1000.0 / memtotal).round() / 10.0;
// assert!(p.mem_pct == mem_pct);

assert!(p.mem_size_kib == size);
assert!(p.resident_kib == rss as usize);
assert!(p.resident_kib == rss);
}

#[test]
Expand Down

0 comments on commit 69eb02e

Please sign in to comment.