#[doc(hidden)]
pub use hotpath_macros_meta::{future_fn, main, measure, measure_all, skip};
use std::sync::OnceLock;
use crate::instant::Instant;
pub(crate) static START_TIME: OnceLock<Instant> = OnceLock::new();
pub(crate) const MAX_DURATION_NS: u64 = 1_000_000_000_000;
#[inline]
pub(crate) fn elapsed_since_start_ns(end: Instant) -> u64 {
START_TIME
.get()
.map(|start| end.duration_since(*start).as_nanos() as u64)
.unwrap_or(0)
}
#[inline]
pub(crate) fn current_elapsed_ns() -> u64 {
START_TIME
.get()
.map(|start| start.elapsed().as_nanos() as u64)
.unwrap_or(0)
}
pub(crate) use hotpath_drain_meta as batch;
pub(crate) mod caller_stack;
pub(crate) mod channels;
#[doc(hidden)]
pub mod debug;
#[doc(hidden)]
pub mod futures;
#[doc(hidden)]
pub mod http;
#[doc(hidden)]
pub mod io;
pub(crate) mod locations;
pub(crate) mod mutexes;
pub(crate) mod rw_locks;
pub(crate) mod server;
pub(crate) mod sql;
pub(crate) mod streams;
#[cfg(feature = "threads")]
pub(crate) mod threads;
#[cfg(feature = "tokio")]
#[doc(hidden)]
pub mod tokio_runtime;
#[doc(hidden)]
pub mod functions;
pub use channels::{InstrumentChannelWrap, InstrumentChannelWrapLog};
pub use futures::{InstrumentFuture, InstrumentFutureLog};
pub use io::io_unwrap;
pub use mutexes::InstrumentMutex;
pub use rw_locks::InstrumentRwLock;
pub use server::AxumLayer;
pub use streams::{InstrumentStream, InstrumentStreamLog};
#[cfg(feature = "hotpath-cloud-meta")]
pub(crate) mod ci_info;
#[cfg(feature = "hotpath-cloud-meta")]
pub(crate) mod cloud;
#[cfg(feature = "hotpath-cloud-meta")]
pub(crate) mod git_info;
pub(crate) mod hotpath_guard;
#[cfg(feature = "hotpath-prometheus-meta")]
pub(crate) mod native_histograms;
pub(crate) mod report;
pub(crate) mod report_meta;
pub(crate) mod sampling;
#[doc(hidden)]
pub use locations::{register_location, Location};
pub use functions::allocator::CountingAllocator;
pub use functions::{
measure_async, measure_async_future, measure_async_future_log, measure_async_log, measure_sync,
measure_sync_log, MeasurementGuardAsync, MeasurementGuardSync,
};
pub use hotpath_guard::{HotpathGuard, HotpathGuardBuilder};
type HostSuspendFn = fn() -> bool;
type HostResumeFn = fn(bool);
static HOST_ALLOC_HOOKS: OnceLock<(HostSuspendFn, HostResumeFn)> = OnceLock::new();
#[doc(hidden)]
pub fn set_host_alloc_suspend_hooks(suspend: HostSuspendFn, resume: HostResumeFn) {
let _ = HOST_ALLOC_HOOKS.set((suspend, resume));
}
#[must_use = "guard is dropped immediately without suspending tracking"]
pub(crate) struct SuspendAllocTracking {
#[cfg(feature = "hotpath-alloc-meta")]
previous_enabled: bool,
host_previous: Option<bool>,
}
impl SuspendAllocTracking {
#[inline]
pub(crate) fn new() -> Self {
let host_previous = HOST_ALLOC_HOOKS.get().map(|(suspend, _)| suspend());
#[cfg(feature = "hotpath-alloc-meta")]
{
let previous_enabled = functions::alloc::core::suspend_alloc_tracking();
Self {
previous_enabled,
host_previous,
}
}
#[cfg(not(feature = "hotpath-alloc-meta"))]
{
Self { host_previous }
}
}
}
impl Drop for SuspendAllocTracking {
#[inline]
fn drop(&mut self) {
#[cfg(feature = "hotpath-alloc-meta")]
functions::alloc::core::resume_alloc_tracking(self.previous_enabled);
if let Some(host_previous) = self.host_previous {
if let Some((_, resume)) = HOST_ALLOC_HOOKS.get() {
resume(host_previous);
}
}
}
}
#[macro_export]
macro_rules! measure_block {
($label:literal, $expr:expr) => {{
$crate::__unique_label!(function, $label);
$crate::measure_block!({ $label }, $expr)
}};
($label:expr, $expr:expr) => {{
let __hotpath_label: &'static str = $label;
{
static __HOTPATH_LOC: $crate::Location = $crate::Location {
file: file!(),
line: line!(),
column: column!(),
};
static __HOTPATH_LAST_LABEL: std::sync::atomic::AtomicPtr<u8> =
std::sync::atomic::AtomicPtr::new(std::ptr::null_mut());
let __hotpath_label_ptr = __hotpath_label.as_ptr() as *mut u8;
if __HOTPATH_LAST_LABEL.load(std::sync::atomic::Ordering::Relaxed)
!= __hotpath_label_ptr
{
$crate::register_location(__hotpath_label, &__HOTPATH_LOC);
__HOTPATH_LAST_LABEL
.store(__hotpath_label_ptr, std::sync::atomic::Ordering::Relaxed);
}
}
let _guard = $crate::functions::build_measurement_guard_block(__hotpath_label, false);
$expr
}};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __register_location {
($id:expr) => {{
static __HOTPATH_LOC: $crate::Location = $crate::Location {
file: file!(),
line: line!(),
column: column!(),
};
static __HOTPATH_LOC_ONCE: std::sync::Once = std::sync::Once::new();
__HOTPATH_LOC_ONCE.call_once(|| $crate::register_location($id, &__HOTPATH_LOC));
}};
}
#[rustfmt::skip]
#[doc(hidden)]
#[macro_export]
macro_rules! __unique_label {
($kind:ident, $label:literal) => {
#[unsafe(export_name = concat!(
"hotpath-meta: duplicate ",
stringify!($kind),
" label \"",
$label,
"\""
))]
static __HOTPATH_UNIQUE_LABEL: u8 = 0;
};
}
#[macro_export]
macro_rules! dbg {
($val:expr $(,)?) => {{
static DBG_ID: std::sync::OnceLock<u32> = std::sync::OnceLock::new();
let id = *DBG_ID.get_or_init(|| {
$crate::debug::DEBUG_ID_COUNTER.fetch_add(1, std::sync::atomic::Ordering::Relaxed)
});
const DBG_LOC: &'static str = concat!(file!(), ":", line!(), ":", column!());
const DBG_EXPR: &'static str = stringify!($val);
$crate::__register_location!(DBG_LOC);
match $val {
tmp => {
$crate::debug::dbg::log_dbg(id, DBG_LOC, DBG_EXPR, &tmp);
tmp
}
}
}};
($($val:expr),+ $(,)?) => {
($($crate::dbg!($val)),+,)
};
}
#[macro_export]
macro_rules! val {
($key:expr) => {{
const VAL_LOC: &'static str = concat!(file!(), ":", line!(), ":", column!());
$crate::__register_location!(VAL_LOC);
$crate::debug::val::ValHandle::new($key, VAL_LOC)
}};
}
#[macro_export]
macro_rules! gauge {
($key:expr) => {{
const GAUGE_LOC: &'static str = concat!(file!(), ":", line!(), ":", column!());
$crate::__register_location!(GAUGE_LOC);
$crate::debug::gauge::GaugeHandle::new($key, GAUGE_LOC)
}};
}
#[macro_export]
macro_rules! tokio_runtime {
() => {
$crate::tokio_runtime::init_runtime_monitoring(&tokio::runtime::Handle::current());
};
($handle:expr) => {
$crate::tokio_runtime::init_runtime_monitoring($handle);
};
}
#[cfg(test)]
mod tests {
use crate::lib_on::HotpathGuard;
fn is_send_sync<T: Send + Sync>() {}
#[test]
fn test_hotpath_is_send_sync() {
is_send_sync::<HotpathGuard>();
}
}