1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
use RecordId;
/// Deferred call chain.
///
/// Needs to be stitched to the previous incomplete call chain
/// to form the full one.
///
/// Can be enabled by [`ExtraRecord::call_chain_deferred`][crate::config::ExtraRecord::call_chain_deferred].
///
/// # Examples
///
/// ```rust
/// # #[cfg(not(feature = "linux-6.19"))]
/// # return;
/// #
/// use perf_event_open::config::{CallChain, Cpu, Opts, Proc, SampleOn};
/// use perf_event_open::count::Counter;
/// use perf_event_open::event::sw::Software;
///
/// let event = Software::TaskClock;
/// let target = (Proc::CURRENT, Cpu::ALL);
///
/// let mut opts = Opts::default();
/// opts.sample_on = SampleOn::Count(1_000_000); // 1ms
/// opts.sample_format.call_chain = Some(CallChain {
/// exclude_user: false,
/// exclude_kernel: false,
/// // Request `CallChain::UserDeferred`.
/// defer_user: true,
/// max_stack_frames: 20,
/// });
/// // Generate `CallChainDeferred` record.
/// opts.extra_record.call_chain_deferred = true;
///
/// let counter = Counter::new(event, target, opts).unwrap();
/// let sampler = counter.sampler(10).unwrap();
///
/// counter.enable().unwrap();
/// // Make some noise to collect call chains.
/// for _ in 0..100000 {
/// unsafe { libc::gettid() };
/// }
/// counter.disable().unwrap();
/// #
/// # let mut user_deferred = false;
/// # let mut call_chain_deferred = false;
///
/// for it in sampler.iter() {
/// println!("{:-?}", it);
/// #
/// # use perf_event_open::sample::record::Record;
/// # use perf_event_open::sample::record::sample::CallChain;
/// # match it.1 {
/// # Record::Sample(s) => {
/// # if s.call_chain
/// # .unwrap()
/// # .iter()
/// # .any(|it| matches!(it, CallChain::UserDeferred { cookie: _ }))
/// # {
/// # user_deferred = true;
/// # }
/// # }
/// # Record::CallChainDeferred(_) => {
/// # call_chain_deferred = true;
/// # }
/// # _ => {}
/// # }
/// }
/// #
/// # assert!(user_deferred);
/// # assert!(call_chain_deferred);
/// ```
///
/// See also [`CallChain::defer_user`][crate::config::CallChain::defer_user]
/// and [`CallChain::UserDeferred`][crate::sample::record::sample::CallChain::UserDeferred].
///
/// Since `linux-6.19`: <https://github.com/torvalds/linux/commit/c69993ecdd4dfde2b7da08b022052a33b203da07>
from!;
debug!;