Skip to main content

ktrace_macro/
lib.rs

1// Copyright 2026 The Fuchsia Authors
2//
3// Use of this source code is governed by a MIT-style
4// license that can be found in the LICENSE file or at
5// https://opensource.org/licenses/MIT
6
7#![no_std]
8// These macros are designed to expand in the kernel root crate where `crate::ktrace_rs`
9// refers to the kernel's tracing module.
10#![allow(clippy::crate_in_macro_def)]
11
12/// Resolves a string parameter to a reference to an `InternedString`.
13/// If a string literal is provided, it is statically interned at compile-time.
14#[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/// Resolves a category parameter to a reference to an `InternedCategory`.
32/// If a string literal is provided, it is declared as an external category.
33#[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/// Returns true if the given trace category is currently enabled.
45#[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/// Writes an instant event associated with the current thread when the given category is enabled.
54///
55/// # Arguments:
56/// - category: Filter category for the event. Expects a string literal or expression.
57/// - label: Label for the event. Expects a string literal or expression.
58/// - ...: List of key => value argument pairs.
59#[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/// Similar to `instant!`, but associates the event with the current CPU instead of the current
86/// thread.
87#[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/// Similar to `duration_begin!`, but accepts an expression to use for the event timestamp.
95#[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/// Writes a duration begin event associated with the current thread when the given category is
128/// enabled.
129///
130/// # Arguments:
131/// - category: Filter category for the event. Expects a string literal or expression.
132/// - label: Label for the event. Expects a string literal or expression.
133/// - ...: List of key => value argument pairs.
134#[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/// Similar to `duration_begin!`, but associates the event with the current CPU instead of the
151/// current thread.
152#[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/// Similar to `duration_end!`, but accepts an expression to use for the event timestamp.
160#[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/// Writes a duration end event associated with the current thread when the given category is
193/// enabled.
194///
195/// # Arguments:
196/// - category: Filter category for the event. Expects a string literal or expression.
197/// - label: Label for the event. Expects a string literal or expression.
198/// - ...: List of key => value argument pairs.
199#[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/// Similar to `duration_end!`, but associates the event with the current CPU instead of the
216/// current thread.
217#[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/// Similar to `counter!`, but accepts an expression to use for the event timestamp.
225#[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/// Similar to `cpu_counter!`, but accepts an expression to use for the event timestamp.
259#[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/// Writes a counter event associated with the current thread when the given category is enabled.
274///
275/// Each argument is rendered as a separate value series named "<label>:<arg name>:<counter_id>".
276///
277/// # Arguments:
278/// - category: Filter category for the event. Expects a string literal or expression.
279/// - label: Label for the event. Expects a string literal or expression.
280/// - counter_id: Correlation id for the event. Must be convertible to u64.
281/// - ...: List of key => value argument pairs.
282#[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/// Similar to `counter!`, but associates the event with the current CPU instead of the current
306/// thread.
307#[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/// Similar to `flow_begin!`, but accepts an expression to use for the event timestamp.
321#[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/// Writes a flow begin event associated with the current thread when the given category is enabled.
355///
356/// # Arguments:
357/// - category: Filter category for the event. Expects a string literal or expression.
358/// - label: Label for the event. Expects a string literal or expression.
359/// - flow_id: Flow id for the event. Must be convertible to u64.
360/// - ...: List of key => value argument pairs.
361#[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/// Similar to `flow_begin!`, but associates the event with the current CPU instead of the current
385/// thread.
386#[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/// Similar to `flow_step!`, but accepts an expression to use for the event timestamp.
400#[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/// Writes a flow step event associated with the current thread when the given category is enabled.
434///
435/// # Arguments:
436/// - category: Filter category for the event. Expects a string literal or expression.
437/// - label: Label for the event. Expects a string literal or expression.
438/// - flow_id: Flow id for the event. Must be convertible to u64.
439/// - ...: List of key => value argument pairs.
440#[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/// Similar to `flow_step!`, but associates the event with the current CPU instead of the current
464/// thread.
465#[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/// Similar to `flow_end!`, but accepts an expression to use for the event timestamp.
479#[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/// Writes a flow end event associated with the current thread when the given category is enabled.
513///
514/// # Arguments:
515/// - category: Filter category for the event. Expects a string literal or expression.
516/// - label: Label for the event. Expects a string literal or expression.
517/// - flow_id: Flow id for the event. Must be convertible to u64.
518/// - ...: List of key => value argument pairs.
519#[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/// Similar to `flow_end!`, but associates the event with the current CPU instead of the current
543/// thread.
544#[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/// Creates a scope guard (`Option<KTraceScope>`) that captures the given arguments at the
558/// beginning of a scope when the given category is enabled, and emits the duration complete event
559/// when dropped or ended via `end_scope!`. The complete event is associated with the current
560/// thread.
561///
562/// # Arguments:
563/// - category: Filter category for the event. Expects a string literal or expression.
564/// - label: Label for the event. Expects a string literal or expression.
565/// - ...: List of key => value argument pairs.
566#[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/// Similar to `begin_scope!`, but associates the event with the current CPU instead of the
574/// current thread.
575#[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/// Similar to `begin_scope!`, but checks the given runtime_condition, in addition to the given
583/// category, to determine whether to emit the event.
584#[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/// Similar to `begin_scope_cond!`, but associates the event with the current CPU instead of the
611/// current thread.
612#[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/// Ends a trace scope created by a begin scope macro with additional key-value argument pairs.
626///
627/// # Arguments:
628/// - scope: The `Option<KTraceScope>` returned by a begin scope macro.
629/// - ...: List of key => value argument pairs.
630#[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/// Writes a duration complete event associated with the current thread when the given category is
645/// enabled.
646///
647/// # Arguments:
648/// - category: Filter category for the event. Expects a string literal or expression.
649/// - label: Label for the event. Expects a string literal or expression.
650/// - start_timestamp: The starting timestamp for the event. Must be convertible to i64.
651/// - ...: List of key => value argument pairs.
652#[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/// Similar to `complete!`, but associates the event with the current CPU instead of the current
679/// thread.
680#[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/// Writes a kernel object record when the given trace category is enabled.
688///
689/// # Arguments:
690/// - category: Filter category for the object record. Expects a string literal or expression.
691/// - koid: Kernel object id of the object. Expects type u64.
692/// - obj_type: The type the object. Expects type u32.
693/// - name: The name of the object. Expects a string literal or expression.
694/// - ...: List of key => value argument pairs.
695#[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/// Writes a kernel object record unconditionally. Useful for generating the initial set of object
715/// info records before tracing is enabled.
716///
717/// # Arguments:
718/// - koid: Kernel object id of the object. Expects type u64.
719/// - obj_type: The type the object. Expects type u32.
720/// - name: The name of the object. Expects a string literal or expression.
721/// - ...: List of key => value argument pairs.
722#[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/// Writes a context switch record for the given threads when the given trace category is enabled.
739///
740/// # Arguments:
741/// - category: Filter category for the event. Expects a string literal or expression.
742/// - cpu: The CPU number on which the context switch occurred.
743/// - outgoing_state: The state of the outgoing thread (`zx_thread_state_t`).
744/// - outgoing_tid: The KOID of the outgoing thread.
745/// - incoming_tid: The KOID of the incoming thread.
746/// - ...: List of key => value argument pairs.
747#[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/// Writes a thread wakeup record for the given thread when the given trace category is enabled.
768///
769/// # Arguments:
770/// - category: Filter category for the event. Expects a string literal or expression.
771/// - cpu: The target CPU number on which the thread is waking.
772/// - incoming_tid: The KOID of the waking thread.
773/// - ...: List of key => value argument pairs.
774#[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}