1use crate::c_headers;
2use crate::taskstats;
3use std::mem;
4use std::time::Duration;
5
6const fn const_max(a: usize, b: usize) -> usize {
8 [a, b][(a < b) as usize]
9}
10
11pub const TASKSTATS_SIZE: usize = const_max(
12 mem::size_of::<taskstats>(),
13 mem::size_of::<c_headers::taskstats>(),
14);
15
16#[derive(Clone, Copy, Debug)]
26pub struct TaskStats {
27 pub(crate) inner_buf: [u8; TASKSTATS_SIZE],
28 pub tid: u32,
30 pub cpu: Cpu,
32 pub memory: Memory,
34 pub io: Io,
36 pub blkio: BlkIo,
38 pub ctx_switches: ContextSwitches,
40 pub delays: Delays,
42}
43
44#[derive(Debug, Clone, Copy)]
46pub struct Cpu {
47 pub utime_total: Duration,
49 pub stime_total: Duration,
51 pub real_time_total: Duration,
53 pub virtual_time_total: Duration,
55}
56
57#[derive(Debug, Clone, Copy)]
59pub struct Memory {
60 pub rss_total: u64,
62 pub virt_total: u64,
64 pub minor_faults: u64,
66 pub major_faults: u64,
68}
69
70#[derive(Debug, Clone, Copy)]
72pub struct Io {
73 pub read_bytes: u64,
75 pub write_bytes: u64,
77 pub read_syscalls: u64,
79 pub write_syscalls: u64,
81}
82
83#[derive(Debug, Clone, Copy)]
85pub struct BlkIo {
86 pub read_bytes: u64,
88 pub write_bytes: u64,
90 pub cancelled_write_bytes: u64,
92}
93
94#[derive(Debug, Clone, Copy)]
96pub struct ContextSwitches {
97 pub voluntary: u64,
99 pub non_voluntary: u64,
101}
102
103#[derive(Debug, Clone, Copy)]
105pub struct Delays {
106 pub cpu: DelayStat,
108 pub blkio: DelayStat,
110 pub swapin: DelayStat,
112 pub freepages: DelayStat,
114}
115
116#[derive(Debug, Clone, Copy)]
117pub struct DelayStat {
118 pub count: u64,
120 pub delay_total: Duration,
122}
123
124impl From<&[u8]> for TaskStats {
125 fn from(buf: &[u8]) -> Self {
126 let mut inner_buf = [0u8; TASKSTATS_SIZE];
127 inner_buf.copy_from_slice(&buf[..TASKSTATS_SIZE]);
128 let ts = unsafe { &*(inner_buf.as_ptr() as *const _ as *const taskstats) };
129 TaskStats {
130 tid: ts.ac_pid,
131 cpu: Cpu {
132 utime_total: Duration::from_micros(ts.ac_utime),
133 stime_total: Duration::from_micros(ts.ac_stime),
134 real_time_total: Duration::from_nanos(ts.cpu_run_real_total),
135 virtual_time_total: Duration::from_nanos(ts.cpu_run_virtual_total),
136 },
137 memory: Memory {
138 rss_total: ts.coremem,
139 virt_total: ts.virtmem,
140 minor_faults: ts.ac_minflt,
141 major_faults: ts.ac_majflt,
142 },
143 io: Io {
144 read_bytes: ts.read_char,
145 write_bytes: ts.write_char,
146 read_syscalls: ts.read_syscalls,
147 write_syscalls: ts.write_syscalls,
148 },
149 blkio: BlkIo {
150 read_bytes: ts.read_bytes,
151 write_bytes: ts.write_bytes,
152 cancelled_write_bytes: ts.cancelled_write_bytes,
153 },
154 ctx_switches: ContextSwitches {
155 voluntary: ts.nvcsw,
156 non_voluntary: ts.nivcsw,
157 },
158 delays: Delays {
159 cpu: DelayStat {
160 count: ts.cpu_count,
161 delay_total: Duration::from_nanos(ts.cpu_delay_total),
162 },
163 blkio: DelayStat {
164 count: ts.blkio_count,
165 delay_total: Duration::from_nanos(ts.blkio_delay_total),
166 },
167 swapin: DelayStat {
168 count: ts.swapin_count,
169 delay_total: Duration::from_nanos(ts.swapin_delay_total),
170 },
171 freepages: DelayStat {
172 count: ts.freepages_count,
173 delay_total: Duration::from_nanos(ts.freepages_delay_total),
174 },
175 },
176 inner_buf,
177 }
178 }
179}
180
181impl TaskStats {
182 pub fn inner(&self) -> &taskstats {
190 unsafe { &*(self.inner_buf.as_ptr() as *const _ as *const taskstats) }
191 }
192}