miden_debug_engine/profiling/instrument/
mod.rs1use miden_core::operations::Operation;
7
8mod op_histogram;
9
10pub use op_histogram::OpHistogram;
11
12pub trait Instrument {
14 fn name(&self) -> &'static str;
18 fn on_operation_execution_cycle(&mut self, op: Operation);
20 fn write_report_to(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()>;
22}
23
24pub trait InstrumentRegistration: Sized + Instrument + 'static {
26 const NAME: &'static str;
28
29 fn build(config: &super::ProfilerConfig) -> Result<Self, InstrumentError>;
31}
32
33#[derive(Debug, thiserror::Error)]
34pub enum InstrumentError {
35 #[error("unknown profiling instrument '{0}'")]
37 Undefined(String),
38 #[error("failed to construct instrument '{name}': {reason}")]
40 Build { name: String, reason: String },
41}
42
43pub fn instrument_from_name(
48 name: &str,
49 config: &super::ProfilerConfig,
50) -> Result<Box<dyn Instrument>, InstrumentError> {
51 for instrument in inventory::iter::<InstrumentRegistrationInfo>() {
52 if instrument.name == name {
53 return (instrument.builder)(config);
54 }
55 }
56 Err(InstrumentError::Undefined(name.to_string()))
57}
58
59#[doc(hidden)]
60pub struct InstrumentRegistrationInfo {
61 name: &'static str,
62 builder: fn(&super::ProfilerConfig) -> Result<Box<dyn Instrument>, InstrumentError>,
63}
64
65impl InstrumentRegistrationInfo {
66 pub const fn new<T: InstrumentRegistration>() -> Self {
67 let name = <T as InstrumentRegistration>::NAME;
68 Self {
69 name,
70 builder: build_instrument::<T>,
71 }
72 }
73}
74
75#[macro_export]
76macro_rules! register_instrument {
77 ($t:ty) => {
78 inventory::submit!($crate::profiling::instrument::InstrumentRegistrationInfo::new::<$t>());
79 };
80}
81
82inventory::collect!(InstrumentRegistrationInfo);
83
84#[inline]
85fn build_instrument<T: InstrumentRegistration>(
86 config: &super::ProfilerConfig,
87) -> Result<Box<dyn Instrument>, InstrumentError> {
88 <T as InstrumentRegistration>::build(config).map(|inst| Box::new(inst) as Box<dyn Instrument>)
89}