Skip to main content

perf_event/
flags.rs

1use bitflags::bitflags;
2
3use crate::sys::bindings;
4use crate::Builder;
5
6used_in_docs!(Builder);
7
8/// Configuration of how much skid is allowed when gathering samples.
9///
10/// Skid is the number of instructions that occur between an event occuring and
11/// a sample being gathered by the kernel. Less skid is better but there are
12/// hardware limitations around how small the skid can be.
13///
14/// Also see [`Builder::precise_ip`].
15#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
16pub enum SampleSkid {
17    /// There may be an arbitrary number of instructions between the event and
18    /// the recorded instruction pointer.
19    Arbitrary = 0,
20
21    /// There may be a constant number of instructions between the event and
22    /// and the recorded instruction pointer.
23    Constant = 1,
24
25    /// We've requested that there be 0 skid. This does not guarantee that
26    /// samples will actually have 0 skid.
27    RequestZero = 2,
28
29    /// Skid must be 0. If skid is 0 then the generated sample records will
30    /// have the `PERF_RECORD_MISC_EXACT_IP` bit set.
31    RequireZero = 3,
32}
33
34/// Supported linux clocks that can be used within a perf_event instance.
35///
36/// See the [`clock_gettime(2)`][0] manpage for the full documentation on what
37/// each clock value actually means.
38///
39/// [0]: https://www.mankier.com/2/clock_gettime
40#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
41#[repr(transparent)]
42pub struct Clock(libc::clockid_t);
43
44impl Clock {
45    /// A clock following International Atomic Time.
46    pub const TAI: Self = Self::new(libc::CLOCK_TAI);
47
48    /// A clock that measures wall-clock time.
49    pub const REALTIME: Self = Self::new(libc::CLOCK_REALTIME);
50
51    /// A clock that is identical to `MONOTONIC` except it also includes any
52    /// time during which the systems was suspended.
53    pub const BOOTTIME: Self = Self::new(libc::CLOCK_BOOTTIME);
54
55    /// A clock that (roughly) corresponds to the time that the system has been
56    /// running since it was booted. (On Linux, at least).
57    pub const MONOTONIC: Self = Self::new(libc::CLOCK_MONOTONIC);
58
59    /// Similar to `MONOTONIC` but does not include NTP adjustments.
60    pub const MONOTONIC_RAW: Self = Self::new(libc::CLOCK_MONOTONIC_RAW);
61}
62
63impl Clock {
64    /// Construct a new `Clock` from the libc clockid value.
65    pub const fn new(clockid: libc::clockid_t) -> Self {
66        Self(clockid)
67    }
68
69    /// Extract the libc clockid value.
70    pub const fn into_raw(self) -> libc::clockid_t {
71        self.0
72    }
73}
74
75bitflags! {
76    /// Specify what branches to include in a branch record.
77    ///
78    /// This is used by the builder in combination with setting
79    /// [`SampleFlag::BRANCH_STACK`].
80    ///
81    /// The first part of the value is the privilege level, which is a
82    /// combination of `USER`, `BRANCH`, or `HV`. `PLM_ALL` is a convenience
83    /// value with all 3 ORed together. If none of the privilege levels are set
84    /// then the kernel will use the privilege level of the event.
85    ///
86    /// The second part specifies which branch types are to be included in the
87    /// branch stack. At least one of these bits must be set.
88    pub struct SampleBranchFlag: u64 {
89        /// The branch target is in user space.
90        const USER = bindings::PERF_SAMPLE_BRANCH_USER as _;
91
92        /// The branch target is in kernel space.
93        const KERNEL = bindings::PERF_SAMPLE_BRANCH_KERNEL as _;
94
95        /// The branch target is in the hypervisor.
96        const HV = bindings::PERF_SAMPLE_BRANCH_HV as _;
97
98        /// Include any branch type.
99        const ANY = bindings::PERF_SAMPLE_BRANCH_ANY as _;
100
101        /// Include any call branch.
102        ///
103        /// This includes direct calls, indirect calls, and far jumps.
104        const ANY_CALL = bindings::PERF_SAMPLE_BRANCH_ANY_CALL as _;
105
106        /// Include indirect calls.
107        const IND_CALL = bindings::PERF_SAMPLE_BRANCH_IND_CALL as _;
108
109        /// Include direct calls.
110        const CALL = bindings::PERF_SAMPLE_BRANCH_CALL as _;
111
112        /// Include any return branch.
113        const ANY_RETURN = bindings::PERF_SAMPLE_BRANCH_ANY_RETURN as _;
114
115        /// Include indirect jumps.
116        const IND_JUMP = bindings::PERF_SAMPLE_BRANCH_IND_JUMP as _;
117
118        /// Include conditional branches.
119        const COND = bindings::PERF_SAMPLE_BRANCH_COND as _;
120
121        /// Include transactional memory aborts.
122        const ABORT_TX = bindings::PERF_SAMPLE_BRANCH_ABORT_TX as _;
123
124        /// Include branches in a transactional memory transaction.
125        const IN_TX = bindings::PERF_SAMPLE_BRANCH_IN_TX as _;
126
127        /// Include branches not in a transactional memory transaction.
128        const NO_TX = bindings::PERF_SAMPLE_BRANCH_NO_TX as _;
129
130        /// Include branches that are part of a hardware-generated call stack.
131        ///
132        /// Note that this requires hardware support. See the [manpage][0] for
133        /// platforms which support this.
134        ///
135        /// [0]: https://www.mankier.com/2/perf_event_open
136        const CALL_STACK = bindings::PERF_SAMPLE_BRANCH_CALL_STACK as _;
137    }
138}
139
140impl SampleBranchFlag {
141    /// All privilege levels (`USER`, `KERNEL`, and `HV`) ORed together.
142    pub const PLM_ALL: Self = Self::USER.union(Self::KERNEL).union(Self::HV);
143}
144
145bitflags! {
146    /// Flags that control what data is returned when reading from a
147    /// perf_event file descriptor.
148    ///
149    /// See the [man page][0] for the authoritative documentation on what
150    /// these flags do.
151    ///
152    /// [0]: http://man7.org/linux/man-pages/man2/perf_event_open.2.html
153    #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
154    pub struct ReadFormat : u64 {
155        /// Emit the total amount of time the counter has spent enabled.
156        const TOTAL_TIME_ENABLED = bindings::PERF_FORMAT_TOTAL_TIME_ENABLED as _;
157
158        /// Emit the total amount of time the counter was actually on the
159        /// CPU.
160        const TOTAL_TIME_RUNNING = bindings::PERF_FORMAT_TOTAL_TIME_RUNNING as _;
161
162        /// Emit the counter ID.
163        const ID = bindings::PERF_FORMAT_ID as _;
164
165        /// If in a group, read all the counters in the group at once.
166        const GROUP = bindings::PERF_FORMAT_GROUP as _;
167
168        /// Emit the number of lost samples for this event.
169        const LOST = bindings::PERF_FORMAT_LOST as _;
170    }
171}