1use std::time::Instant;
2
3use crate::DiagCtxtHandle;
4
5#[derive(Copy, Clone, Debug)]
7pub enum TimingSection {
8 Linking,
10}
11
12#[derive(Copy, Clone, Debug)]
14pub struct TimingRecord {
15 pub section: TimingSection,
16 pub timestamp: u128,
18}
19
20impl TimingRecord {
21 fn from_origin(origin: Instant, section: TimingSection) -> Self {
22 Self { section, timestamp: Instant::now().duration_since(origin).as_micros() }
23 }
24
25 pub fn section(&self) -> TimingSection {
26 self.section
27 }
28
29 pub fn timestamp(&self) -> u128 {
30 self.timestamp
31 }
32}
33
34pub struct TimingSectionHandler {
36 origin: Option<Instant>,
39}
40
41impl TimingSectionHandler {
42 pub fn new(enabled: bool) -> Self {
43 let origin = if enabled { Some(Instant::now()) } else { None };
44 Self { origin }
45 }
46
47 pub fn start_section<'a>(
50 &self,
51 diag_ctxt: DiagCtxtHandle<'a>,
52 section: TimingSection,
53 ) -> TimingSectionGuard<'a> {
54 TimingSectionGuard::create(diag_ctxt, section, self.origin)
55 }
56}
57
58pub struct TimingSectionGuard<'a> {
60 dcx: DiagCtxtHandle<'a>,
61 section: TimingSection,
62 origin: Option<Instant>,
63}
64
65impl<'a> TimingSectionGuard<'a> {
66 fn create(dcx: DiagCtxtHandle<'a>, section: TimingSection, origin: Option<Instant>) -> Self {
67 if let Some(origin) = origin {
68 dcx.emit_timing_section_start(TimingRecord::from_origin(origin, section));
69 }
70 Self { dcx, section, origin }
71 }
72}
73
74impl<'a> Drop for TimingSectionGuard<'a> {
75 fn drop(&mut self) {
76 if let Some(origin) = self.origin {
77 self.dcx.emit_timing_section_end(TimingRecord::from_origin(origin, self.section));
78 }
79 }
80}