use crate::c_headers;
use crate::taskstats;
use std::mem;
use std::time::Duration;
const fn const_max(a: usize, b: usize) -> usize {
[a, b][(a < b) as usize]
}
pub const TASKSTATS_SIZE: usize = const_max(
mem::size_of::<taskstats>(),
mem::size_of::<c_headers::taskstats>(),
);
#[derive(Clone, Copy, Debug)]
pub struct TaskStats {
pub(crate) inner_buf: [u8; TASKSTATS_SIZE],
pub tid: u32,
pub cpu: Cpu,
pub memory: Memory,
pub io: Io,
pub blkio: BlkIo,
pub ctx_switches: ContextSwitches,
pub delays: Delays,
}
#[derive(Debug, Clone, Copy)]
pub struct Cpu {
pub utime_total: Duration,
pub stime_total: Duration,
pub real_time_total: Duration,
pub virtual_time_total: Duration,
}
#[derive(Debug, Clone, Copy)]
pub struct Memory {
pub rss_total: u64,
pub virt_total: u64,
pub minor_faults: u64,
pub major_faults: u64,
}
#[derive(Debug, Clone, Copy)]
pub struct Io {
pub read_bytes: u64,
pub write_bytes: u64,
pub read_syscalls: u64,
pub write_syscalls: u64,
}
#[derive(Debug, Clone, Copy)]
pub struct BlkIo {
pub read_bytes: u64,
pub write_bytes: u64,
pub cancelled_write_bytes: u64,
}
#[derive(Debug, Clone, Copy)]
pub struct ContextSwitches {
pub voluntary: u64,
pub non_voluntary: u64,
}
#[derive(Debug, Clone, Copy)]
pub struct Delays {
pub cpu: DelayStat,
pub blkio: DelayStat,
pub swapin: DelayStat,
pub freepages: DelayStat,
}
#[derive(Debug, Clone, Copy)]
pub struct DelayStat {
pub count: u64,
pub delay_total: Duration,
}
impl From<&[u8]> for TaskStats {
fn from(buf: &[u8]) -> Self {
let mut inner_buf = [0u8; TASKSTATS_SIZE];
inner_buf.copy_from_slice(&buf[..TASKSTATS_SIZE]);
let ts = unsafe { &*(inner_buf.as_ptr() as *const _ as *const taskstats) };
TaskStats {
tid: ts.ac_pid,
cpu: Cpu {
utime_total: Duration::from_micros(ts.ac_utime),
stime_total: Duration::from_micros(ts.ac_stime),
real_time_total: Duration::from_nanos(ts.cpu_run_real_total),
virtual_time_total: Duration::from_nanos(ts.cpu_run_virtual_total),
},
memory: Memory {
rss_total: ts.coremem,
virt_total: ts.virtmem,
minor_faults: ts.ac_minflt,
major_faults: ts.ac_majflt,
},
io: Io {
read_bytes: ts.read_char,
write_bytes: ts.write_char,
read_syscalls: ts.read_syscalls,
write_syscalls: ts.write_syscalls,
},
blkio: BlkIo {
read_bytes: ts.read_bytes,
write_bytes: ts.write_bytes,
cancelled_write_bytes: ts.cancelled_write_bytes,
},
ctx_switches: ContextSwitches {
voluntary: ts.nvcsw,
non_voluntary: ts.nivcsw,
},
delays: Delays {
cpu: DelayStat {
count: ts.cpu_count,
delay_total: Duration::from_nanos(ts.cpu_delay_total),
},
blkio: DelayStat {
count: ts.blkio_count,
delay_total: Duration::from_nanos(ts.blkio_delay_total),
},
swapin: DelayStat {
count: ts.swapin_count,
delay_total: Duration::from_nanos(ts.swapin_delay_total),
},
freepages: DelayStat {
count: ts.freepages_count,
delay_total: Duration::from_nanos(ts.freepages_delay_total),
},
},
inner_buf,
}
}
}
impl TaskStats {
pub fn inner(&self) -> &taskstats {
unsafe { &*(self.inner_buf.as_ptr() as *const _ as *const taskstats) }
}
}