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