profile_traits/lib.rs
1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5//! This module contains APIs for the `profile` crate used generically in the
6//! rest of Servo. These APIs are here instead of in `profile` so that these
7//! modules won't have to depend on `profile`.
8
9#![deny(unsafe_code)]
10
11pub mod generic_callback;
12pub mod generic_channel;
13pub mod ipc;
14pub mod mem;
15pub mod time;
16
17/// Measure the given callback with the time profiler and (if enabled) tracing.
18///
19/// `$category` must be const, because we use it to derive the span name.
20#[macro_export]
21macro_rules! time_profile {
22 ($category:expr, $meta:expr, $profiler_chan:expr, $($callback:tt)+) => {{
23 let meta: Option<$crate::time::TimerMetadata> = $meta;
24 #[cfg(feature = "tracing")]
25 let span = $crate::servo_tracing::info_span!(
26 $category.variant_name(),
27 servo_profiling = true,
28 url = meta.as_ref().map(|m| m.url.clone()),
29 );
30 #[cfg(not(feature = "tracing"))]
31 let span = ();
32 $crate::time::profile($category, meta, $profiler_chan, span, $($callback)+)
33 }};
34}
35
36#[doc(hidden)]
37#[macro_export]
38macro_rules! __profiling_span {
39 ($backend_macro:ident, $span_name:literal $(, $($fields:tt)+)?) => {{
40 #[cfg(feature = "tracing")]
41 {
42 $crate::servo_tracing::$backend_macro!(
43 $span_name,
44 servo_profiling = true
45 $(, $($fields)+)?
46 )
47 }
48 #[cfg(not(feature = "tracing"))]
49 {
50 $crate::dummy_tracing::Span()
51 }
52 }};
53}
54
55#[doc(hidden)]
56#[macro_export]
57macro_rules! __profiling_event {
58 ($backend_macro:ident, $event_name:literal $(, $($fields:tt)+)?) => {{
59 #[cfg(feature = "tracing")]
60 $crate::servo_tracing::$backend_macro!(
61 name: $event_name,
62 servo_profiling = true
63 $(, $($fields)+)?
64 );
65 }};
66}
67
68/// Provides API compatible dummies for the tracing-rs APIs we use
69/// if tracing is disabled. Hence, nothing will be traced
70pub mod dummy_tracing {
71 use std::fmt::Display;
72 use std::marker::PhantomData;
73
74 pub struct Span();
75
76 pub struct EnteredSpan(Span);
77 pub struct Entered<'a>(PhantomData<&'a Span>);
78
79 impl Span {
80 pub fn enter(&self) -> Entered<'_> {
81 Entered(PhantomData)
82 }
83
84 pub fn entered(self) -> EnteredSpan {
85 EnteredSpan(self)
86 }
87
88 pub fn in_scope<F: FnOnce() -> T, T>(&self, f: F) -> T {
89 // We still need to execute the function, even if tracing is disabled.
90 f()
91 }
92 }
93
94 impl EnteredSpan {}
95
96 impl Entered<'_> {}
97
98 #[derive(Debug)]
99 struct Level();
100
101 #[expect(dead_code)]
102 impl Level {
103 /// The "error" level.
104 ///
105 /// Designates very serious errors.
106 pub const ERROR: Level = Level();
107 /// The "warn" level.
108 ///
109 /// Designates hazardous situations.
110 pub const WARN: Level = Level();
111 /// The "info" level.
112 ///
113 /// Designates useful information.
114 pub const INFO: Level = Level();
115 /// The "debug" level.
116 ///
117 /// Designates lower priority information.
118 pub const DEBUG: Level = Level();
119 /// The "trace" level.
120 ///
121 /// Designates very low priority, often extremely verbose, information.
122 pub const TRACE: Level = Level();
123 /// Returns the string representation of the `Level`.
124 ///
125 /// This returns the same string as the `fmt::Display` implementation.
126 pub fn as_str(&self) -> &'static str {
127 "disabled"
128 }
129 }
130 impl Display for Level {
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 write!(f, "{}", self.as_str())
133 }
134 }
135}
136
137/// Constructs a span at the trace level
138///
139/// This macro creates a Span for the purpose of instrumenting code to measure
140/// the execution time of the span.
141/// If the `tracing` feature (of the crate using this macro) is disabled, then
142/// the Span implementation will be replaced with a dummy, that does not record
143/// anything.
144///
145/// Attention: This macro requires the user crate to have a `tracing` feature,
146/// which can be used to disable the effects of this macro.
147#[macro_export]
148macro_rules! trace_span {
149 ($span_name:literal $(, $($fields:tt)+)?) => {
150 $crate::__profiling_span!(trace_span, $span_name $(, $($fields)+)?)
151 };
152}
153
154/// Constructs a span at the debug level
155///
156/// This macro creates a Span for the purpose of instrumenting code to measure
157/// the execution time of the span.
158/// If the `tracing` feature (of the crate using this macro) is disabled, then
159/// the Span implementation will be replaced with a dummy, that does not record
160/// anything.
161///
162/// Attention: This macro requires the user crate to have a `tracing` feature,
163/// which can be used to disable the effects of this macro.
164#[macro_export]
165macro_rules! debug_span {
166 ($span_name:literal $(, $($fields:tt)+)?) => {
167 $crate::__profiling_span!(debug_span, $span_name $(, $($fields)+)?)
168 };
169}
170
171/// Constructs a span at the info level
172///
173/// This macro creates a Span for the purpose of instrumenting code to measure
174/// the execution time of the span.
175/// If the `tracing` feature (of the crate using this macro) is disabled, then
176/// the Span implementation will be replaced with a dummy, that does not record
177/// anything.
178///
179/// Attention: This macro requires the user crate to have a `tracing` feature,
180/// which can be used to disable the effects of this macro.
181#[macro_export]
182macro_rules! info_span {
183 ($span_name:literal $(, $($fields:tt)+)?) => {
184 $crate::__profiling_span!(info_span, $span_name $(, $($fields)+)?)
185 };
186}
187
188/// Emit an event at the trace level
189///
190/// This macro creates an Event for the purpose of instrumenting code to measure
191/// the execution time between events.
192///
193/// If the `tracing` feature (of the crate using this macro) is disabled, this
194/// macro expands to nothing.
195///
196/// Attention: This macro requires the user crate to have a `tracing` feature,
197/// which can be used to disable the effects of this macro.
198#[macro_export]
199macro_rules! trace_event {
200 ($event_name:literal $(, $($fields:tt)+)?) => {
201 $crate::__profiling_event!(trace, $event_name $(, $($fields)+)?)
202 };
203}
204
205/// Emit an event at the debug level
206///
207/// This macro creates an Event for the purpose of instrumenting code to measure
208/// the execution time between events.
209///
210/// If the `tracing` feature (of the crate using this macro) is disabled, this
211/// macro expands to nothing.
212///
213/// Attention: This macro requires the user crate to have a `tracing` feature,
214/// which can be used to disable the effects of this macro.
215#[macro_export]
216macro_rules! debug_event {
217 ($event_name:literal $(, $($fields:tt)+)?) => {
218 $crate::__profiling_event!(debug, $event_name $(, $($fields)+)?)
219 };
220}
221
222/// Emit an event at the info level
223///
224/// This macro creates an Event for the purpose of instrumenting code to measure
225/// the execution time between events.
226///
227/// If the `tracing` feature (of the crate using this macro) is disabled, this
228/// macro expands to nothing.
229///
230/// Attention: This macro requires the user crate to have a `tracing` feature,
231/// which can be used to disable the effects of this macro.
232#[macro_export]
233macro_rules! info_event {
234 ($event_name:literal $(, $($fields:tt)+)?) => {
235 $crate::__profiling_event!(info, $event_name $(, $($fields)+)?)
236 };
237}
238
239#[cfg(feature = "tracing")]
240pub use tracing as servo_tracing;