#![allow(dead_code)]
#![allow(clippy::field_reassign_with_default)]
use std::collections::BTreeMap;
use super::*;
use crate::ctprof::{CgroupStats, CtprofSnapshot, ThreadState};
use crate::metric_types::{CategoricalString, CpuSet, MonotonicCount, MonotonicNs, OrdinalI32};
pub(super) fn make_thread(pcomm: &str, comm: &str) -> ThreadState {
ThreadState {
tid: 1,
tgid: 1,
pcomm: pcomm.into(),
comm: comm.into(),
cgroup: "/".into(),
start_time_clock_ticks: 0,
policy: CategoricalString("SCHED_OTHER".into()),
nice: OrdinalI32(0),
cpu_affinity: CpuSet(vec![0, 1, 2, 3]),
..ThreadState::default()
}
}
pub(super) fn snap_with(threads: Vec<ThreadState>) -> CtprofSnapshot {
CtprofSnapshot {
captured_at_unix_ns: 0,
host: None,
threads,
cgroup_stats: BTreeMap::new(),
probe_summary: None,
parse_summary: None,
taskstats_summary: None,
psi: crate::ctprof::Psi::default(),
sched_ext: None,
}
}
pub(super) fn simple_cgroup_stats(
cpu_usage_usec: u64,
nr_throttled: u64,
throttled_usec: u64,
memory_current: u64,
) -> CgroupStats {
let mut cs = CgroupStats::default();
cs.cpu.usage_usec = cpu_usage_usec;
cs.cpu.nr_throttled = nr_throttled;
cs.cpu.throttled_usec = throttled_usec;
cs.memory.current = memory_current;
cs
}
pub(super) fn lookup_metric(name: &str) -> &'static CtprofMetricDef {
CTPROF_METRICS
.iter()
.find(|m| m.name == name)
.unwrap_or_else(|| panic!("metric {name} registered"))
}
pub(super) fn snap_pair_for_display() -> (CtprofSnapshot, CtprofSnapshot) {
let mut a = make_thread("p", "w");
a.run_time_ns = MonotonicNs(100);
a.wait_count = MonotonicCount(4);
a.wait_sum = MonotonicNs(1000);
let mut b = make_thread("p", "w");
b.run_time_ns = MonotonicNs(200);
b.wait_count = MonotonicCount(4);
b.wait_sum = MonotonicNs(2000);
(snap_with(vec![a]), snap_with(vec![b]))
}
pub(super) fn smaps_thread(pcomm: &str, tgid: u32, rss_kb: u64, pss_kb: u64) -> ThreadState {
let mut t = ThreadState {
tid: tgid,
tgid,
pcomm: pcomm.into(),
comm: pcomm.into(),
cgroup: "/".into(),
..ThreadState::default()
};
t.smaps_rollup_kb.insert("Rss".into(), rss_kb);
t.smaps_rollup_kb.insert("Pss".into(), pss_kb);
t
}
pub(super) const FUDGE_WORDS: &[&str] = &[
"alpha", "beta", "gamma", "delta", "epsilon", "zeta", "eta", "theta", "iota", "kappa",
"lambda", "mu", "nu", "xi", "omicron", "pi", "rho", "sigma", "tau", "upsilon", "phi", "chi",
"psi", "omega",
];
pub(super) fn fudge_snap(cgroup: &str, n: usize, _pcomm_prefix: &str) -> CtprofSnapshot {
assert!(
n <= FUDGE_WORDS.len(),
"fudge_snap: requested n={n} exceeds the literal-pcomm vocabulary",
);
let mut threads = Vec::new();
for (i, word) in FUDGE_WORDS.iter().enumerate().take(n) {
let pcomm = word.to_string();
let comm = format!("{word}-w");
let mut t = make_thread(&pcomm, &comm);
t.tid = (1000 + i) as u32;
t.tgid = t.tid;
t.cgroup = cgroup.into();
threads.push(t);
}
snap_with(threads)
}
pub(super) fn fudge_compose(snaps: Vec<CtprofSnapshot>) -> CtprofSnapshot {
let mut threads = Vec::new();
for snap in snaps {
threads.extend(snap.threads);
}
snap_with(threads)
}
pub(super) fn fudge_compare(a: &CtprofSnapshot, b: &CtprofSnapshot) -> CtprofDiff {
compare(
a,
b,
&CompareOptions {
group_by: GroupBy::All.into(),
cgroup_flatten: vec![],
no_thread_normalize: false,
no_cg_normalize: false,
sort_by: Vec::new(),
},
)
}
pub(super) fn fudge_threads_with<F: FnMut(&mut ThreadState)>(
cgroup: &str,
n: usize,
mut tweak: F,
) -> Vec<ThreadState> {
assert!(
n <= FUDGE_WORDS.len(),
"fudge_threads_with: requested n={n} exceeds the literal-pcomm vocabulary",
);
let mut threads = Vec::new();
for (i, word) in FUDGE_WORDS.iter().enumerate().take(n) {
let mut t = make_thread(word, &format!("{word}-w"));
t.tid = (1000 + i) as u32;
t.tgid = t.tid;
t.cgroup = cgroup.into();
tweak(&mut t);
threads.push(t);
}
threads
}
#[allow(dead_code)]
pub(super) fn _fudge_helpers_used() {
let _ = fudge_compose;
}