1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//! Startup phase timing. The launcher builds its table list before the window
//! exists, so anything slow in that path delays the first frame; these logs
//! say where the time goes.
use std::sync::OnceLock;
use std::time::Instant;
static START: OnceLock<Instant> = OnceLock::new();
/// Mark the process start. Call first thing in `main`.
pub fn init() {
let _ = START.set(Instant::now());
}
/// Milliseconds since [`init`].
pub fn since_start_ms() -> u128 {
START.get().map_or(0, |s| s.elapsed().as_millis())
}
/// A named phase; logs its duration and the time since process start when
/// finished.
pub struct Phase {
name: &'static str,
t0: Instant,
}
impl Phase {
pub fn start(name: &'static str) -> Self {
Self {
name,
t0: Instant::now(),
}
}
pub fn done(self) {
log::info!(
"startup: {} took {} ms (at +{} ms)",
self.name,
self.t0.elapsed().as_millis(),
since_start_ms()
);
}
}