perf_event_data/
flags.rs

1#![allow(missing_docs)]
2
3use bitflags::bitflags;
4use perf_event_open_sys::bindings;
5
6use crate::Sample;
7
8used_in_docs!(Sample);
9
10bitflags! {
11    /// Specifies which fields to include in the sample.
12    ///
13    /// These values correspond to `PERF_SAMPLE_x` values. See the
14    /// [manpage] for documentation on what they mean.
15    ///
16    /// [manpage]: http://man7.org/linux/man-pages/man2/perf_event_open.2.html
17    #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
18    pub struct SampleFlags : u64 {
19        const IP = bindings::PERF_SAMPLE_IP as _;
20        const TID = bindings::PERF_SAMPLE_TID as _;
21        const TIME = bindings::PERF_SAMPLE_TIME as _;
22        const ADDR = bindings::PERF_SAMPLE_ADDR as _;
23        const READ = bindings::PERF_SAMPLE_READ as _;
24        const CALLCHAIN = bindings::PERF_SAMPLE_CALLCHAIN as _;
25        const ID = bindings::PERF_SAMPLE_ID as _;
26        const CPU = bindings::PERF_SAMPLE_CPU as _;
27        const PERIOD = bindings::PERF_SAMPLE_PERIOD as _;
28        const STREAM_ID = bindings::PERF_SAMPLE_STREAM_ID as _;
29        const RAW = bindings::PERF_SAMPLE_RAW as _;
30        const BRANCH_STACK = bindings::PERF_SAMPLE_BRANCH_STACK as _;
31        const REGS_USER = bindings::PERF_SAMPLE_REGS_USER as _;
32        const STACK_USER = bindings::PERF_SAMPLE_STACK_USER as _;
33        const WEIGHT = bindings::PERF_SAMPLE_WEIGHT as _;
34        const DATA_SRC = bindings::PERF_SAMPLE_DATA_SRC as _;
35        const IDENTIFIER = bindings::PERF_SAMPLE_IDENTIFIER as _;
36        const TRANSACTION = bindings::PERF_SAMPLE_TRANSACTION as _;
37        const REGS_INTR = bindings::PERF_SAMPLE_REGS_INTR as _;
38        const PHYS_ADDR = bindings::PERF_SAMPLE_PHYS_ADDR as _;
39        const AUX = bindings::PERF_SAMPLE_AUX as _;
40        const CGROUP = bindings::PERF_SAMPLE_CGROUP as _;
41
42        // The following are present in perf_event.h but not yet documented
43        // in the manpage.
44        const DATA_PAGE_SIZE = bindings::PERF_SAMPLE_DATA_PAGE_SIZE as _;
45        const CODE_PAGE_SIZE = bindings::PERF_SAMPLE_CODE_PAGE_SIZE as _;
46        const WEIGHT_STRUCT = bindings::PERF_SAMPLE_WEIGHT_STRUCT as _;
47    }
48}
49
50bitflags! {
51    /// Flags that control what data is returned when reading from a
52    /// perf_event file descriptor.
53    ///
54    /// See the [man page][0] for the authoritative documentation on what
55    /// these flags do.
56    ///
57    /// [0]: http://man7.org/linux/man-pages/man2/perf_event_open.2.html
58    #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Default)]
59    pub struct ReadFormat : u64 {
60        /// Emit the total amount of time the counter has spent enabled.
61        const TOTAL_TIME_ENABLED = bindings::PERF_FORMAT_TOTAL_TIME_ENABLED as _;
62
63        /// Emit the total amount of time the counter was actually on the
64        /// CPU.
65        const TOTAL_TIME_RUNNING = bindings::PERF_FORMAT_TOTAL_TIME_RUNNING as _;
66
67        /// Emit the counter ID.
68        const ID = bindings::PERF_FORMAT_ID as _;
69
70        /// If in a group, read all the counters in the group at once.
71        const GROUP = bindings::PERF_FORMAT_GROUP as _;
72
73        /// Emit the number of lost samples for this event.
74        const LOST = bindings::PERF_FORMAT_LOST as _;
75    }
76}
77
78impl ReadFormat {
79    // The format of a read from a group is like this
80    // struct read_format {
81    //     u64 nr;            /* The number of events */
82    //     u64 time_enabled;  /* if PERF_FORMAT_TOTAL_TIME_ENABLED */
83    //     u64 time_running;  /* if PERF_FORMAT_TOTAL_TIME_RUNNING */
84    //     struct {
85    //         u64 value;     /* The value of the event */
86    //         u64 id;        /* if PERF_FORMAT_ID */
87    //         u64 lost;      /* if PERF_FORMAT_LOST */
88    //     } values[nr];
89    // };
90
91    /// The size of each element when reading a group
92    pub(crate) fn element_len(&self) -> usize {
93        1 + (*self & (Self::ID | Self::LOST)).bits().count_ones() as usize
94    }
95}
96
97#[cfg(feature = "arbitrary")]
98mod fuzzing {
99    use super::*;
100
101    use arbitrary::{Arbitrary, Result, Unstructured};
102
103    impl<'a> Arbitrary<'a> for SampleFlags {
104        fn arbitrary(u: &mut Unstructured) -> Result<Self> {
105            Ok(Self::from_bits_retain(Arbitrary::arbitrary(u)?))
106        }
107    }
108
109    impl<'a> Arbitrary<'a> for ReadFormat {
110        fn arbitrary(u: &mut Unstructured) -> Result<Self> {
111            Ok(Self::from_bits_retain(Arbitrary::arbitrary(u)?))
112        }
113    }
114}