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