1#![no_std]
8#![allow(clippy::crate_in_macro_def)]
11
12#[macro_export]
15macro_rules! resolve_string {
16 ($string:ident) => {
17 $string
18 };
19 ($string:literal) => {{
20 #[unsafe(link_section = "__fxt_interned_string_table")]
21 #[used]
22 static STRING: crate::ktrace_rs::InternedString =
23 unsafe { crate::ktrace_rs::InternedString::new_raw(concat!($string, "\0").as_ptr()) };
24 &STRING
25 }};
26 ($string:expr) => {
27 $string
28 };
29}
30
31#[macro_export]
34macro_rules! resolve_category {
35 ($category:ident) => {
36 $category
37 };
38 ($category:literal) => {{
39 crate::ktrace_rs::declare_interned_category!(CATEGORY, $category, extern);
40 CATEGORY
41 }};
42}
43
44#[macro_export]
46macro_rules! category_enabled {
47 ($category:tt) => {{
48 let category = $crate::resolve_category!($category);
49 crate::ktrace_rs::KTrace::category_enabled(category)
50 }};
51}
52
53#[macro_export]
60macro_rules! instant {
61 ($category:tt, $label:tt, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
62 {
63 let category = $crate::resolve_category!($category);
64 if crate::ktrace_rs::KTrace::category_enabled(category) {
65 crate::ktrace_rs::KTrace::emit_event(
66 crate::ktrace_rs::EventType::Instant,
67 category,
68 $crate::resolve_string!($label),
69 crate::ktrace_rs::KTrace::timestamp(),
70 $context,
71 None,
72 &[
73 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
74 ],
75 &[],
76 );
77 }
78 }
79 };
80 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
81 $crate::instant!($category, $label, crate::ktrace_rs::Context::Thread $(, $key => $val)*)
82 };
83}
84
85#[macro_export]
88macro_rules! cpu_instant {
89 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
90 $crate::instant!($category, $label, crate::ktrace_rs::Context::Cpu $(, $key => $val)*)
91 };
92}
93
94#[macro_export]
96macro_rules! duration_begin_timestamp {
97 ($category:tt, $label:tt, $timestamp:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
98 {
99 let category = $crate::resolve_category!($category);
100 if crate::ktrace_rs::KTrace::category_enabled(category) {
101 crate::ktrace_rs::KTrace::emit_event(
102 crate::ktrace_rs::EventType::DurationBegin,
103 category,
104 $crate::resolve_string!($label),
105 $timestamp,
106 $context,
107 None,
108 &[
109 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
110 ],
111 &[],
112 );
113 }
114 }
115 };
116 ($category:tt, $label:tt, $timestamp:expr $(, $key:tt => $val:expr)* $(,)?) => {
117 $crate::duration_begin_timestamp!(
118 $category,
119 $label,
120 $timestamp,
121 crate::ktrace_rs::Context::Thread
122 $(, $key => $val)*
123 )
124 };
125}
126
127#[macro_export]
135macro_rules! duration_begin {
136 ($category:tt, $label:tt, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
137 $crate::duration_begin_timestamp!(
138 $category,
139 $label,
140 crate::ktrace_rs::KTrace::timestamp(),
141 $context
142 $(, $key => $val)*
143 )
144 };
145 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
146 $crate::duration_begin!($category, $label, crate::ktrace_rs::Context::Thread $(, $key => $val)*)
147 };
148}
149
150#[macro_export]
153macro_rules! cpu_duration_begin {
154 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
155 $crate::duration_begin!($category, $label, crate::ktrace_rs::Context::Cpu $(, $key => $val)*)
156 };
157}
158
159#[macro_export]
161macro_rules! duration_end_timestamp {
162 ($category:tt, $label:tt, $timestamp:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
163 {
164 let category = $crate::resolve_category!($category);
165 if crate::ktrace_rs::KTrace::category_enabled(category) {
166 crate::ktrace_rs::KTrace::emit_event(
167 crate::ktrace_rs::EventType::DurationEnd,
168 category,
169 $crate::resolve_string!($label),
170 $timestamp,
171 $context,
172 None,
173 &[
174 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
175 ],
176 &[],
177 );
178 }
179 }
180 };
181 ($category:tt, $label:tt, $timestamp:expr $(, $key:tt => $val:expr)* $(,)?) => {
182 $crate::duration_end_timestamp!(
183 $category,
184 $label,
185 $timestamp,
186 crate::ktrace_rs::Context::Thread
187 $(, $key => $val)*
188 )
189 };
190}
191
192#[macro_export]
200macro_rules! duration_end {
201 ($category:tt, $label:tt, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
202 $crate::duration_end_timestamp!(
203 $category,
204 $label,
205 crate::ktrace_rs::KTrace::timestamp(),
206 $context
207 $(, $key => $val)*
208 )
209 };
210 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
211 $crate::duration_end!($category, $label, crate::ktrace_rs::Context::Thread $(, $key => $val)*)
212 };
213}
214
215#[macro_export]
218macro_rules! cpu_duration_end {
219 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
220 $crate::duration_end!($category, $label, crate::ktrace_rs::Context::Cpu $(, $key => $val)*)
221 };
222}
223
224#[macro_export]
226macro_rules! counter_timestamp {
227 ($category:tt, $label:tt, $timestamp:expr, $counter_id:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
228 {
229 let category = $crate::resolve_category!($category);
230 if crate::ktrace_rs::KTrace::category_enabled(category) {
231 crate::ktrace_rs::KTrace::emit_event(
232 crate::ktrace_rs::EventType::Counter,
233 category,
234 $crate::resolve_string!($label),
235 $timestamp,
236 $context,
237 Some($counter_id as u64),
238 &[
239 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
240 ],
241 &[],
242 );
243 }
244 }
245 };
246 ($category:tt, $label:tt, $timestamp:expr, $counter_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
247 $crate::counter_timestamp!(
248 $category,
249 $label,
250 $timestamp,
251 $counter_id,
252 crate::ktrace_rs::Context::Thread
253 $(, $key => $val)*
254 )
255 };
256}
257
258#[macro_export]
260macro_rules! cpu_counter_timestamp {
261 ($category:tt, $label:tt, $timestamp:expr, $counter_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
262 $crate::counter_timestamp!(
263 $category,
264 $label,
265 $timestamp,
266 $counter_id,
267 crate::ktrace_rs::Context::Cpu
268 $(, $key => $val)*
269 )
270 };
271}
272
273#[macro_export]
283macro_rules! counter {
284 ($category:tt, $label:tt, $counter_id:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
285 $crate::counter_timestamp!(
286 $category,
287 $label,
288 crate::ktrace_rs::KTrace::timestamp(),
289 $counter_id,
290 $context
291 $(, $key => $val)*
292 )
293 };
294 ($category:tt, $label:tt, $counter_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
295 $crate::counter!(
296 $category,
297 $label,
298 $counter_id,
299 crate::ktrace_rs::Context::Thread
300 $(, $key => $val)*
301 )
302 };
303}
304
305#[macro_export]
308macro_rules! cpu_counter {
309 ($category:tt, $label:tt, $counter_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
310 $crate::counter!(
311 $category,
312 $label,
313 $counter_id,
314 crate::ktrace_rs::Context::Cpu
315 $(, $key => $val)*
316 )
317 };
318}
319
320#[macro_export]
322macro_rules! flow_begin_timestamp {
323 ($category:tt, $label:tt, $timestamp:expr, $flow_id:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
324 {
325 let category = $crate::resolve_category!($category);
326 if crate::ktrace_rs::KTrace::category_enabled(category) {
327 crate::ktrace_rs::KTrace::emit_event(
328 crate::ktrace_rs::EventType::FlowBegin,
329 category,
330 $crate::resolve_string!($label),
331 $timestamp,
332 $context,
333 Some($flow_id as u64),
334 &[
335 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
336 ],
337 &[],
338 );
339 }
340 }
341 };
342 ($category:tt, $label:tt, $timestamp:expr, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
343 $crate::flow_begin_timestamp!(
344 $category,
345 $label,
346 $timestamp,
347 $flow_id,
348 crate::ktrace_rs::Context::Thread
349 $(, $key => $val)*
350 )
351 };
352}
353
354#[macro_export]
362macro_rules! flow_begin {
363 ($category:tt, $label:tt, $flow_id:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
364 $crate::flow_begin_timestamp!(
365 $category,
366 $label,
367 crate::ktrace_rs::KTrace::timestamp(),
368 $flow_id,
369 $context
370 $(, $key => $val)*
371 )
372 };
373 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
374 $crate::flow_begin!(
375 $category,
376 $label,
377 $flow_id,
378 crate::ktrace_rs::Context::Thread
379 $(, $key => $val)*
380 )
381 };
382}
383
384#[macro_export]
387macro_rules! cpu_flow_begin {
388 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
389 $crate::flow_begin!(
390 $category,
391 $label,
392 $flow_id,
393 crate::ktrace_rs::Context::Cpu
394 $(, $key => $val)*
395 )
396 };
397}
398
399#[macro_export]
401macro_rules! flow_step_timestamp {
402 ($category:tt, $label:tt, $timestamp:expr, $flow_id:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
403 {
404 let category = $crate::resolve_category!($category);
405 if crate::ktrace_rs::KTrace::category_enabled(category) {
406 crate::ktrace_rs::KTrace::emit_event(
407 crate::ktrace_rs::EventType::FlowStep,
408 category,
409 $crate::resolve_string!($label),
410 $timestamp,
411 $context,
412 Some($flow_id as u64),
413 &[
414 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
415 ],
416 &[],
417 );
418 }
419 }
420 };
421 ($category:tt, $label:tt, $timestamp:expr, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
422 $crate::flow_step_timestamp!(
423 $category,
424 $label,
425 $timestamp,
426 $flow_id,
427 crate::ktrace_rs::Context::Thread
428 $(, $key => $val)*
429 )
430 };
431}
432
433#[macro_export]
441macro_rules! flow_step {
442 ($category:tt, $label:tt, $flow_id:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
443 $crate::flow_step_timestamp!(
444 $category,
445 $label,
446 crate::ktrace_rs::KTrace::timestamp(),
447 $flow_id,
448 $context
449 $(, $key => $val)*
450 )
451 };
452 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
453 $crate::flow_step!(
454 $category,
455 $label,
456 $flow_id,
457 crate::ktrace_rs::Context::Thread
458 $(, $key => $val)*
459 )
460 };
461}
462
463#[macro_export]
466macro_rules! cpu_flow_step {
467 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
468 $crate::flow_step!(
469 $category,
470 $label,
471 $flow_id,
472 crate::ktrace_rs::Context::Cpu
473 $(, $key => $val)*
474 )
475 };
476}
477
478#[macro_export]
480macro_rules! flow_end_timestamp {
481 ($category:tt, $label:tt, $timestamp:expr, $flow_id:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
482 {
483 let category = $crate::resolve_category!($category);
484 if crate::ktrace_rs::KTrace::category_enabled(category) {
485 crate::ktrace_rs::KTrace::emit_event(
486 crate::ktrace_rs::EventType::FlowEnd,
487 category,
488 $crate::resolve_string!($label),
489 $timestamp,
490 $context,
491 Some($flow_id as u64),
492 &[
493 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
494 ],
495 &[],
496 );
497 }
498 }
499 };
500 ($category:tt, $label:tt, $timestamp:expr, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
501 $crate::flow_end_timestamp!(
502 $category,
503 $label,
504 $timestamp,
505 $flow_id,
506 crate::ktrace_rs::Context::Thread
507 $(, $key => $val)*
508 )
509 };
510}
511
512#[macro_export]
520macro_rules! flow_end {
521 ($category:tt, $label:tt, $flow_id:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
522 $crate::flow_end_timestamp!(
523 $category,
524 $label,
525 crate::ktrace_rs::KTrace::timestamp(),
526 $flow_id,
527 $context
528 $(, $key => $val)*
529 )
530 };
531 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
532 $crate::flow_end!(
533 $category,
534 $label,
535 $flow_id,
536 crate::ktrace_rs::Context::Thread
537 $(, $key => $val)*
538 )
539 };
540}
541
542#[macro_export]
545macro_rules! cpu_flow_end {
546 ($category:tt, $label:tt, $flow_id:expr $(, $key:tt => $val:expr)* $(,)?) => {
547 $crate::flow_end!(
548 $category,
549 $label,
550 $flow_id,
551 crate::ktrace_rs::Context::Cpu
552 $(, $key => $val)*
553 )
554 };
555}
556
557#[macro_export]
567macro_rules! begin_scope {
568 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
569 $crate::begin_scope_cond!(true, $category, $label $(, $key => $val)*)
570 };
571}
572
573#[macro_export]
576macro_rules! cpu_begin_scope {
577 ($category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
578 $crate::cpu_begin_scope_cond!(true, $category, $label $(, $key => $val)*)
579 };
580}
581
582#[macro_export]
585macro_rules! begin_scope_cond {
586 ($cond:expr, $category:tt, $label:tt, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {{
587 let category = $crate::resolve_category!($category);
588 if $cond && crate::ktrace_rs::KTrace::category_enabled(category) {
589 Some(crate::ktrace_rs::KTraceScope::begin(
590 category,
591 $crate::resolve_string!($label),
592 $context,
593 [$(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*],
594 ))
595 } else {
596 None
597 }
598 }};
599 ($cond:expr, $category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
600 $crate::begin_scope_cond!(
601 $cond,
602 $category,
603 $label,
604 crate::ktrace_rs::Context::Thread
605 $(, $key => $val)*
606 )
607 };
608}
609
610#[macro_export]
613macro_rules! cpu_begin_scope_cond {
614 ($cond:expr, $category:tt, $label:tt $(, $key:tt => $val:expr)* $(,)?) => {
615 $crate::begin_scope_cond!(
616 $cond,
617 $category,
618 $label,
619 crate::ktrace_rs::Context::Cpu
620 $(, $key => $val)*
621 )
622 };
623}
624
625#[macro_export]
631macro_rules! end_scope {
632 ($scope:expr $(, $key:tt => $val:expr)* $(,)?) => {
633 if let Some(mut scope) = $scope {
634 if !scope.is_ended() {
635 scope.end_with_args(&[
636 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
637 ]);
638 }
639 core::mem::forget(scope);
640 }
641 };
642}
643
644#[macro_export]
653macro_rules! complete {
654 ($category:tt, $label:tt, $start_timestamp:expr, $context:expr $(, $key:tt => $val:expr)* $(,)?) => {
655 {
656 let category = $crate::resolve_category!($category);
657 if crate::ktrace_rs::KTrace::category_enabled(category) {
658 crate::ktrace_rs::KTrace::emit_event(
659 crate::ktrace_rs::EventType::DurationComplete,
660 category,
661 $crate::resolve_string!($label),
662 $start_timestamp,
663 $context,
664 Some(crate::ktrace_rs::KTrace::timestamp().0 as u64),
665 &[
666 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
667 ],
668 &[],
669 );
670 }
671 }
672 };
673 ($category:tt, $label:tt, $start_timestamp:expr $(, $key:tt => $val:expr)* $(,)?) => {
674 $crate::complete!($category, $label, $start_timestamp, crate::ktrace_rs::Context::Thread $(, $key => $val)*)
675 };
676}
677
678#[macro_export]
681macro_rules! cpu_complete {
682 ($category:tt, $label:tt, $start_timestamp:expr $(, $key:tt => $val:expr)* $(,)?) => {
683 $crate::complete!($category, $label, $start_timestamp, crate::ktrace_rs::Context::Cpu $(, $key => $val)*)
684 };
685}
686
687#[macro_export]
696macro_rules! kernel_object {
697 ($category:tt, $koid:expr, $obj_type:expr, $name:expr $(, $key:tt => $val:expr)* $(,)?) => {
698 {
699 let category = $crate::resolve_category!($category);
700 if crate::ktrace_rs::KTrace::category_enabled(category) {
701 crate::ktrace_rs::KTrace::emit_kernel_object_outlined(
702 $koid as u64,
703 $obj_type as u32,
704 $crate::resolve_string!($name),
705 &[
706 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
707 ],
708 );
709 }
710 }
711 };
712}
713
714#[macro_export]
723macro_rules! kernel_object_always {
724 ($koid:expr, $obj_type:expr, $name:expr $(, $key:tt => $val:expr)* $(,)?) => {
725 {
726 crate::ktrace_rs::KTrace::emit_kernel_object_outlined(
727 $koid as u64,
728 $obj_type as u32,
729 $crate::resolve_string!($name),
730 &[
731 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
732 ],
733 );
734 }
735 };
736}
737
738#[macro_export]
748macro_rules! context_switch {
749 ($category:tt, $cpu:expr, $outgoing_state:expr, $outgoing_tid:expr, $incoming_tid:expr $(, $key:tt => $val:expr)* $(,)?) => {
750 {
751 let category = $crate::resolve_category!($category);
752 if crate::ktrace_rs::KTrace::category_enabled(category) {
753 crate::ktrace_rs::KTrace::emit_context_switch(
754 $cpu as u16,
755 $outgoing_state as u32,
756 $outgoing_tid as u64,
757 $incoming_tid as u64,
758 &[
759 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
760 ],
761 );
762 }
763 }
764 };
765}
766
767#[macro_export]
775macro_rules! thread_wakeup {
776 ($category:tt, $cpu:expr, $incoming_tid:expr $(, $key:tt => $val:expr)* $(,)?) => {
777 {
778 let category = $crate::resolve_category!($category);
779 if crate::ktrace_rs::KTrace::category_enabled(category) {
780 crate::ktrace_rs::KTrace::emit_thread_wakeup(
781 $cpu as u16,
782 $incoming_tid as u64,
783 &[
784 $(crate::ktrace_rs::Argument::new($crate::resolve_string!($key), $val)),*
785 ],
786 );
787 }
788 }
789 };
790}