diff --git a/measureme/src/lib.rs b/measureme/src/lib.rs index 032aaae..aabaeea 100644 --- a/measureme/src/lib.rs +++ b/measureme/src/lib.rs @@ -50,7 +50,7 @@ pub mod stringtable; pub mod rustc; pub use crate::event_id::{EventId, EventIdBuilder}; -pub use crate::profiler::{Profiler, TimingGuard}; +pub use crate::profiler::{Profiler, TimingGuard, DetachedTiming}; pub use crate::raw_event::{RawEvent, MAX_INSTANT_TIMESTAMP, MAX_INTERVAL_TIMESTAMP}; pub use crate::serialization::{ split_streams, Addr, PageTag, SerializationSink, SerializationSinkBuilder, diff --git a/measureme/src/profiler.rs b/measureme/src/profiler.rs index f4dd3bb..d243d0f 100644 --- a/measureme/src/profiler.rs +++ b/measureme/src/profiler.rs @@ -122,6 +122,45 @@ impl Profiler { } } + /// Creates a "start" event and returns a `DetachedTiming`. + /// To create the corresponding "event" event, you must call + /// `finish_recording_internal_event` with the returned + /// `DetachedTiming`. + /// Since `DetachedTiming` does not capture the lifetime of `&self`, + /// this method can sometimes be more convenient than + /// `start_recording_interval_event` - e.g. it can be stored + /// in a struct without the need to add a lifetime parameter. + #[inline] + pub fn start_recording_interval_event_detached( + &self, + event_kind: StringId, + event_id: EventId, + thread_id: u32 + ) -> DetachedTiming { + DetachedTiming { + event_id, + event_kind, + thread_id, + start_count: self.counter.since_start(), + } + } + + /// Creates the corresponding "end" event for + /// the "start" event represented by `timing`. You + /// must have obtained `timing` from the same `Profiler` + pub fn finish_recording_interval_event( + &self, + timing: DetachedTiming + ) { + drop(TimingGuard { + profiler: self, + event_id: timing.event_id, + event_kind: timing.event_kind, + thread_id: timing.thread_id, + start_count: timing.start_count, + }); + } + fn record_raw_event(&self, raw_event: &RawEvent) { self.event_sink .write_atomic(std::mem::size_of::(), |bytes| { @@ -130,6 +169,17 @@ impl Profiler { } } +/// Created by `Profiler::start_recording_interval_event_detached`. +/// Must be passed to `finish_recording_interval_event` to record an +/// "end" event. +#[must_use] +pub struct DetachedTiming { + event_id: EventId, + event_kind: StringId, + thread_id: u32, + start_count: u64, +} + /// When dropped, this `TimingGuard` will record an "end" event in the /// `Profiler` it was created by. #[must_use]