1#![no_std]
6
7#[macro_export]
10macro_rules! resolve_string {
11 ($string:ident) => {
12 $string
13 };
14 ($string:literal) => {{
15 #[unsafe(link_section = "__fxt_interned_string_table")]
16 #[used]
17 static STRING: ::ktrace_rs::InternedString =
18 unsafe { ::ktrace_rs::InternedString::new_raw(concat!($string, "\0").as_ptr()) };
19 &STRING
20 }};
21}
22
23#[macro_export]
26macro_rules! resolve_category {
27 ($category:ident) => {
28 $category
29 };
30 ($category:literal) => {{
31 ::ktrace_rs::declare_interned_category!(CATEGORY, $category, extern);
32 CATEGORY
33 }};
34}
35
36#[macro_export]
43macro_rules! instant {
44 ($category:tt, $label:tt, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
45 {
46 let category = $crate::resolve_category!($category);
47 let ktrace = ::ktrace_rs::KTrace::get_instance();
48 if ktrace.is_category_enabled(category) {
49 ktrace.emit_event(
50 ::ktrace_rs::EventType::Instant,
51 category,
52 $crate::resolve_string!($label),
53 ::ktrace_rs::timer_current_boot_ticks(),
54 $context,
55 None,
56 &[
57 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
58 ],
59 );
60 }
61 }
62 };
63 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
64 $crate::instant!($category, $label, ::ktrace_rs::Context::Thread $(, $key => $val)*)
65 };
66}
67
68#[macro_export]
71macro_rules! cpu_instant {
72 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
73 $crate::instant!($category, $label, ::ktrace_rs::Context::Cpu $(, $key => $val)*)
74 };
75}
76
77#[macro_export]
85macro_rules! duration_begin {
86 ($category:tt, $label:tt, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
87 {
88 let category = $crate::resolve_category!($category);
89 let ktrace = ::ktrace_rs::KTrace::get_instance();
90 if ktrace.is_category_enabled(category) {
91 ktrace.emit_event(
92 ::ktrace_rs::EventType::DurationBegin,
93 category,
94 $crate::resolve_string!($label),
95 ::ktrace_rs::timer_current_boot_ticks(),
96 $context,
97 None,
98 &[
99 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
100 ],
101 );
102 }
103 }
104 };
105 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
106 $crate::duration_begin!($category, $label, ::ktrace_rs::Context::Thread $(, $key => $val)*)
107 };
108}
109
110#[macro_export]
113macro_rules! cpu_duration_begin {
114 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
115 $crate::duration_begin!($category, $label, ::ktrace_rs::Context::Cpu $(, $key => $val)*)
116 };
117}
118
119#[macro_export]
127macro_rules! duration_end {
128 ($category:tt, $label:tt, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
129 {
130 let category = $crate::resolve_category!($category);
131 let ktrace = ::ktrace_rs::KTrace::get_instance();
132 if ktrace.is_category_enabled(category) {
133 ktrace.emit_event(
134 ::ktrace_rs::EventType::DurationEnd,
135 category,
136 $crate::resolve_string!($label),
137 ::ktrace_rs::timer_current_boot_ticks(),
138 $context,
139 None,
140 &[
141 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
142 ],
143 );
144 }
145 }
146 };
147 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
148 $crate::duration_end!($category, $label, ::ktrace_rs::Context::Thread $(, $key => $val)*)
149 };
150}
151
152#[macro_export]
155macro_rules! cpu_duration_end {
156 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
157 $crate::duration_end!($category, $label, ::ktrace_rs::Context::Cpu $(, $key => $val)*)
158 };
159}
160
161#[macro_export]
171macro_rules! counter {
172 ($category:tt, $label:tt, $counter_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
173 {
174 let category = $crate::resolve_category!($category);
175 let ktrace = ::ktrace_rs::KTrace::get_instance();
176 if ktrace.is_category_enabled(category) {
177 ktrace.emit_event(
178 ::ktrace_rs::EventType::Counter,
179 category,
180 $crate::resolve_string!($label),
181 ::ktrace_rs::timer_current_boot_ticks(),
182 ::ktrace_rs::Context::Thread,
183 Some($counter_id as u64),
184 &[
185 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
186 ],
187 );
188 }
189 }
190 };
191}
192
193#[macro_export]
201macro_rules! flow_begin {
202 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
203 {
204 let category = $crate::resolve_category!($category);
205 let ktrace = ::ktrace_rs::KTrace::get_instance();
206 if ktrace.is_category_enabled(category) {
207 ktrace.emit_event(
208 ::ktrace_rs::EventType::FlowBegin,
209 category,
210 $crate::resolve_string!($label),
211 ::ktrace_rs::timer_current_boot_ticks(),
212 ::ktrace_rs::Context::Thread,
213 Some($flow_id as u64),
214 &[
215 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
216 ],
217 );
218 }
219 }
220 };
221}
222
223#[macro_export]
231macro_rules! flow_step {
232 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
233 {
234 let category = $crate::resolve_category!($category);
235 let ktrace = ::ktrace_rs::KTrace::get_instance();
236 if ktrace.is_category_enabled(category) {
237 ktrace.emit_event(
238 ::ktrace_rs::EventType::FlowStep,
239 category,
240 $crate::resolve_string!($label),
241 ::ktrace_rs::timer_current_boot_ticks(),
242 ::ktrace_rs::Context::Thread,
243 Some($flow_id as u64),
244 &[
245 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
246 ],
247 );
248 }
249 }
250 };
251}
252
253#[macro_export]
261macro_rules! flow_end {
262 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
263 {
264 let category = $crate::resolve_category!($category);
265 let ktrace = ::ktrace_rs::KTrace::get_instance();
266 if ktrace.is_category_enabled(category) {
267 ktrace.emit_event(
268 ::ktrace_rs::EventType::FlowEnd,
269 category,
270 $crate::resolve_string!($label),
271 ::ktrace_rs::timer_current_boot_ticks(),
272 ::ktrace_rs::Context::Thread,
273 Some($flow_id as u64),
274 &[
275 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
276 ],
277 );
278 }
279 }
280 };
281}
282
283#[macro_export]
293macro_rules! begin_scope {
294 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
295 ::ktrace_rs::KTraceScope::begin(
296 $crate::resolve_category!($category),
297 $crate::resolve_string!($label),
298 ::ktrace_rs::Context::Thread,
299 &[$(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*],
300 )
301 };
302}
303
304#[macro_export]
307macro_rules! cpu_begin_scope {
308 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
309 ::ktrace_rs::KTraceScope::begin(
310 $crate::resolve_category!($category),
311 $crate::resolve_string!($label),
312 ::ktrace_rs::Context::Cpu,
313 &[$(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*],
314 )
315 };
316}
317
318#[macro_export]
321macro_rules! begin_scope_cond {
322 ($cond:expr, $category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
323 {
324 let category = $crate::resolve_category!($category);
325 let ktrace = ::ktrace_rs::KTrace::get_instance();
326 if $cond && ktrace.is_category_enabled(category) {
327 Some(::ktrace_rs::KTraceScope::begin(
328 category,
329 $crate::resolve_string!($label),
330 ::ktrace_rs::Context::Thread,
331 &[$(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*],
332 ))
333 } else {
334 None
335 }
336 }
337 };
338}
339
340#[macro_export]
349macro_rules! complete {
350 ($category:tt, $label:tt, $start_timestamp:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
351 {
352 let category = $crate::resolve_category!($category);
353 let ktrace = ::ktrace_rs::KTrace::get_instance();
354 if ktrace.is_category_enabled(category) {
355 ktrace.emit_event(
356 ::ktrace_rs::EventType::DurationComplete,
357 category,
358 $crate::resolve_string!($label),
359 $start_timestamp,
360 $context,
361 Some(::ktrace_rs::timer_current_boot_ticks().0 as u64),
362 &[
363 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
364 ],
365 );
366 }
367 }
368 };
369 ($category:tt, $label:tt, $start_timestamp:expr $(, $key:tt => $val:expr)* $(,)?) => {
370 $crate::complete!($category, $label, $start_timestamp, ::ktrace_rs::Context::Thread $(, $key => $val)*)
371 };
372}
373
374#[macro_export]
377macro_rules! cpu_complete {
378 ($category:tt, $label:tt, $start_timestamp:expr $(, $key:tt => $val:expr)* $(,)?) => {
379 $crate::complete!($category, $label, $start_timestamp, ::ktrace_rs::Context::Cpu $(, $key => $val)*)
380 };
381}
382
383#[macro_export]
392macro_rules! kernel_object {
393 ($category:tt, $koid:expr, $obj_type:expr, $name:tt $(, $key:tt => $val:expr)* $(,)?) => {
394 {
395 let category = $crate::resolve_category!($category);
396 let ktrace = ::ktrace_rs::KTrace::get_instance();
397 if ktrace.is_category_enabled(category) {
398 ktrace.emit_kernel_object_outlined(
399 $koid as u64,
400 $obj_type as u32,
401 $crate::resolve_string!($name),
402 &[
403 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
404 ],
405 );
406 }
407 }
408 };
409}
410
411#[macro_export]
420macro_rules! kernel_object_always {
421 ($koid:expr, $obj_type:expr, $name:tt $(, $key:tt => $val:expr)* $(,)?) => {
422 {
423 let ktrace = ::ktrace_rs::KTrace::get_instance();
424 ktrace.emit_kernel_object_outlined(
425 $koid as u64,
426 $obj_type as u32,
427 $crate::resolve_string!($name),
428 &[
429 $(::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
430 ],
431 );
432 }
433 };
434}