#[cfg(feature = "enable")]
use crate::Str;
#[cfg(not(feature = "enable"))]
type Str = String;
#[cfg_attr(feature = "enable", derive(Debug))]
pub struct ScopeGuard {}
impl ScopeGuard {
#[inline(always)]
#[allow(unused)]
pub fn new(name: impl Into<Str>) -> Self {
#[cfg(feature = "enable")]
crate::measure::THREAD_PROFILER.with_borrow_mut(|thread| thread.push(name.into()));
Self {}
}
}
impl Drop for ScopeGuard {
fn drop(&mut self) {
#[cfg(feature = "enable")]
{
let time = minstant::Instant::now();
crate::measure::THREAD_PROFILER.with_borrow_mut(|thread| {
thread.pop(time);
})
}
}
}
#[allow(dead_code)]
pub struct ProfiDrop<W: std::io::Write, F: Fn(&mut W)>(W, F);
impl<W, F> ProfiDrop<W, F>
where
W: std::io::Write,
F: Fn(&mut W),
{
pub fn new(to: W, ondrop: F) -> Self {
Self(to, ondrop)
}
}
#[cfg(feature = "enable")]
impl<W, F> std::ops::Drop for ProfiDrop<W, F>
where
W: std::io::Write,
F: Fn(&mut W),
{
fn drop(&mut self) {
drop_threads();
block_until_exited();
print_timings_to(&mut self.0).unwrap();
let s = &self.1;
s(&mut self.0)
}
}
#[inline(always)]
pub fn dbg_thread() {
#[cfg(feature = "enable")]
crate::measure::THREAD_PROFILER.with_borrow(|t| println!("{t:#?}"));
}
#[cfg(feature = "enable")]
fn drop_threads() {
crate::measure::THREAD_PROFILER.with_borrow_mut(|t| {
t.manual_drop(true);
#[cfg(feature = "rayon")]
{
let current = std::thread::current().id();
rayon::broadcast(|t| {
if std::thread::current().id() != current {
crate::measure::THREAD_PROFILER.with_borrow_mut(|t| t.manual_drop(false))
}
});
}
});
}
#[cfg(feature = "enable")]
fn block_until_exited() {
#[cfg(feature = "enable")]
let mut threads = crate::measure::GLOBAL_PROFILER.threads.lock().unwrap();
#[cfg(feature = "enable")]
while *threads > 1 {
threads = crate::measure::GLOBAL_PROFILER.cvar.wait(threads).unwrap();
}
}
#[inline(always)]
pub fn print_timings() -> std::io::Result<()> {
#[cfg(feature = "enable")]
crate::measure::GLOBAL_PROFILER.print_timings(std::io::stdout().lock())?;
Ok(())
}
#[inline(always)]
pub fn eprint_timings() -> std::io::Result<()> {
#[cfg(feature = "enable")]
crate::measure::GLOBAL_PROFILER.print_timings(std::io::stderr())?;
Ok(())
}
#[inline(always)]
#[allow(unused)]
pub fn print_timings_to(to: impl std::io::Write) -> std::io::Result<()> {
#[cfg(feature = "enable")]
crate::measure::GLOBAL_PROFILER.print_timings(to)?;
Ok(())
}
#[cfg(feature = "nightly")]
#[inline(always)]
pub const fn type_name_of(f: fn()) -> &'static str {
std::any::type_name_of_val(&f)
}
#[cfg(not(feature = "nightly"))]
#[inline(always)]
pub fn type_name_of<T>(_: T) -> &'static str {
std::any::type_name::<T>()
}