perf_event_data/records/
switch_cpu_wide.rs

1use perf_event_open_sys::bindings::PERF_RECORD_MISC_SWITCH_OUT;
2
3use crate::prelude::*;
4
5/// SWITCH_CPU_WIDE records indicates a context switch when profiling in
6/// cpu-wide mode.
7///
8/// It provides some additional info on the process being switched that is not
9/// provided by SWITCH.
10///
11/// If the `PERF_RECORD_MISC_SWITCH_OUT` bit is set within the record header
12/// then it was a context switch away from the current process, otherwise it is
13/// a context switch into the current process.
14///
15/// This enum corresponds to `PERF_RECORD_SWITCH_CPU_WIDE`. See the [manpage]
16/// for more documentation.
17///
18/// [manpage]: http://man7.org/linux/man-pages/man2/perf_event_open.2.html
19#[derive(Copy, Clone, Debug)]
20pub enum SwitchCpuWide {
21    /// A context switch into the current process.
22    In {
23        /// The process ID of the process being switched into.
24        pid: u32,
25
26        /// The thread IF of the thread being switched into.
27        tid: u32,
28    },
29
30    /// A context switch away from the current process.
31    Out {
32        /// The process ID of the process being switched away from.
33        pid: u32,
34
35        /// The thread ID of the thread being switched away from.
36        tid: u32,
37    },
38}
39
40impl SwitchCpuWide {
41    /// The process ID associated with the switch.
42    pub fn pid(&self) -> u32 {
43        match *self {
44            Self::In { pid, .. } | Self::Out { pid, .. } => pid,
45        }
46    }
47
48    /// The thread ID associated with the switch.
49    pub fn tid(&self) -> u32 {
50        match *self {
51            Self::In { tid, .. } | Self::Out { tid, .. } => tid,
52        }
53    }
54}
55
56impl<'p> Parse<'p> for SwitchCpuWide {
57    fn parse<B, E>(p: &mut Parser<B, E>) -> ParseResult<Self>
58    where
59        E: Endian,
60        B: ParseBuf<'p>,
61    {
62        let pid = p.parse()?;
63        let tid = p.parse()?;
64
65        if p.config().misc() & PERF_RECORD_MISC_SWITCH_OUT as u16 != 0 {
66            Ok(Self::Out { pid, tid })
67        } else {
68            Ok(Self::In { pid, tid })
69        }
70    }
71}