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/// Provides API compatible dummies for the tracing-rs APIs we use
37/// if tracing is disabled. Hence, nothing will be traced
38pub mod dummy_tracing {
39 use std::fmt::Display;
40 use std::marker::PhantomData;
41
42 pub struct Span();
43
44 pub struct EnteredSpan(Span);
45 pub struct Entered<'a>(PhantomData<&'a Span>);
46
47 impl Span {
48 pub fn enter(&self) -> Entered<'_> {
49 Entered(PhantomData)
50 }
51
52 pub fn entered(self) -> EnteredSpan {
53 EnteredSpan(self)
54 }
55
56 pub fn in_scope<F: FnOnce() -> T, T>(&self, f: F) -> T {
57 // We still need to execute the function, even if tracing is disabled.
58 f()
59 }
60 }
61
62 impl EnteredSpan {}
63
64 impl Entered<'_> {}
65
66 #[derive(Debug)]
67 struct Level();
68
69 #[expect(dead_code)]
70 impl Level {
71 /// The "error" level.
72 ///
73 /// Designates very serious errors.
74 pub const ERROR: Level = Level();
75 /// The "warn" level.
76 ///
77 /// Designates hazardous situations.
78 pub const WARN: Level = Level();
79 /// The "info" level.
80 ///
81 /// Designates useful information.
82 pub const INFO: Level = Level();
83 /// The "debug" level.
84 ///
85 /// Designates lower priority information.
86 pub const DEBUG: Level = Level();
87 /// The "trace" level.
88 ///
89 /// Designates very low priority, often extremely verbose, information.
90 pub const TRACE: Level = Level();
91 /// Returns the string representation of the `Level`.
92 ///
93 /// This returns the same string as the `fmt::Display` implementation.
94 pub fn as_str(&self) -> &'static str {
95 "disabled"
96 }
97 }
98 impl Display for Level {
99 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
100 write!(f, "{}", self.as_str())
101 }
102 }
103}
104
105/// Constructs a span at the trace level
106///
107/// This macro creates a Span for the purpose of instrumenting code to measure
108/// the execution time of the span.
109/// If the `tracing` feature (of the crate using this macro) is disabled, then
110/// the Span implementation will be replaced with a dummy, that does not record
111/// anything.
112///
113/// Attention: This macro requires the user crate to have a `tracing` feature,
114/// which can be used to disable the effects of this macro.
115#[macro_export]
116macro_rules! trace_span {
117 ($span_name:literal, $($field:tt)*) => {
118 {
119 #[cfg(feature = "tracing")]
120 {
121 $crate::servo_tracing::trace_span!(
122 $span_name,
123 servo_profiling = true,
124 $($field)*
125 )
126 }
127 #[cfg(not(feature = "tracing"))]
128 { $crate::dummy_tracing::Span() }
129 }
130 };
131 ($span_name:literal) => {
132 {
133 #[cfg(feature = "tracing")]
134 {
135 $crate::servo_tracing::trace_span!(
136 $span_name,
137 servo_profiling = true,
138 )
139 }
140 #[cfg(not(feature = "tracing"))]
141 { $crate::dummy_tracing::Span() }
142 }
143 };
144}
145
146/// Constructs a span at the info level
147///
148/// This macro creates a Span for the purpose of instrumenting code to measure
149/// the execution time of the span.
150/// If the `tracing` feature (of the crate using this macro) is disabled, then
151/// the Span implementation will be replaced with a dummy, that does not record
152/// anything.
153///
154/// Attention: This macro requires the user crate to have a `tracing` feature,
155/// which can be used to disable the effects of this macro.
156#[macro_export]
157macro_rules! info_span {
158 ($span_name:literal, $($field:tt)*) => {
159 {
160 #[cfg(feature = "tracing")]
161 {
162 $crate::servo_tracing::info_span!(
163 $span_name,
164 servo_profiling = true,
165 $($field)*
166 )
167 }
168 #[cfg(not(feature = "tracing"))]
169 { $crate::dummy_tracing::Span() }
170 }
171 };
172 ($span_name:literal) => {
173 {
174 #[cfg(feature = "tracing")]
175 {
176 $crate::servo_tracing::info_span!(
177 $span_name,
178 servo_profiling = true,
179 )
180 }
181 #[cfg(not(feature = "tracing"))]
182 { $crate::dummy_tracing::Span() }
183 }
184 };
185}
186
187#[cfg(feature = "tracing")]
188pub use tracing as servo_tracing;