#[cfg(target_os = "linux")]
use quanta::Instant;
#[cfg(not(target_os = "linux"))]
use std::time::Instant;
use super::super::truncate_result;
#[must_use = "guard is dropped immediately without measuring anything"]
pub struct MeasurementGuard {
name: &'static str,
wrapper: bool,
unsupported_async: bool,
tid: u64,
start: Instant,
}
impl MeasurementGuard {
#[inline]
pub fn new(name: &'static str, wrapper: bool, unsupported_async: bool) -> Self {
if !unsupported_async {
super::core::ALLOCATIONS.with(|stack| {
let current_depth = stack.depth.get();
stack.depth.set(current_depth + 1);
assert!((stack.depth.get() as usize) < super::core::MAX_DEPTH);
let depth = stack.depth.get() as usize;
stack.elements[depth].bytes_total.set(0);
stack.elements[depth].count_total.set(0);
stack.elements[depth].unsupported_async.set(false);
});
}
Self {
name,
wrapper,
unsupported_async,
tid: crate::tid::current_tid(),
start: Instant::now(),
}
}
}
impl Drop for MeasurementGuard {
#[inline]
fn drop(&mut self) {
let duration = self.start.elapsed();
let cross_thread = crate::tid::current_tid() != self.tid;
let (bytes_total, count_total, unsupported_async) =
if self.unsupported_async || cross_thread {
(0, 0, self.unsupported_async)
} else {
super::core::ALLOCATIONS.with(|stack| {
let depth = stack.depth.get() as usize;
let bytes = stack.elements[depth].bytes_total.get();
let count = stack.elements[depth].count_total.get();
let unsup_async = stack.elements[depth].unsupported_async.get();
stack.depth.set(stack.depth.get() - 1);
if !super::shared::is_alloc_self_enabled() {
let parent = stack.depth.get() as usize;
stack.elements[parent]
.bytes_total
.set(stack.elements[parent].bytes_total.get() + bytes);
stack.elements[parent]
.count_total
.set(stack.elements[parent].count_total.get() + count);
stack.elements[parent]
.unsupported_async
.set(stack.elements[parent].unsupported_async.get() | unsup_async);
}
(bytes, count, unsup_async)
})
};
super::core::ALLOCATIONS.with(|stack| {
stack.tracking_enabled.set(false);
});
let tid = if cross_thread { None } else { Some(self.tid) };
super::state::send_alloc_measurement(
self.name,
bytes_total,
count_total,
duration,
unsupported_async,
self.wrapper,
cross_thread,
tid,
);
super::core::ALLOCATIONS.with(|stack| {
stack.tracking_enabled.set(true);
});
}
}
#[must_use = "guard is dropped immediately without measuring anything"]
pub struct MeasurementGuardWithLog {
name: &'static str,
wrapper: bool,
unsupported_async: bool,
tid: u64,
start: Instant,
finished: bool,
}
impl MeasurementGuardWithLog {
#[inline]
pub fn new(name: &'static str, wrapper: bool, unsupported_async: bool) -> Self {
if !unsupported_async {
super::core::ALLOCATIONS.with(|stack| {
let current_depth = stack.depth.get();
stack.depth.set(current_depth + 1);
assert!((stack.depth.get() as usize) < super::core::MAX_DEPTH);
let depth = stack.depth.get() as usize;
stack.elements[depth].bytes_total.set(0);
stack.elements[depth].count_total.set(0);
stack.elements[depth].unsupported_async.set(false);
});
}
Self {
name,
wrapper,
unsupported_async,
tid: crate::tid::current_tid(),
start: Instant::now(),
finished: false,
}
}
#[inline]
pub fn finish_with_result<T: std::fmt::Debug>(mut self, result: &T) {
self.finished = true;
let result_str = truncate_result(format!("{:?}", result));
let duration = self.start.elapsed();
let cross_thread = crate::tid::current_tid() != self.tid;
let (bytes_total, count_total, unsupported_async) =
if self.unsupported_async || cross_thread {
(0, 0, self.unsupported_async)
} else {
super::core::ALLOCATIONS.with(|stack| {
let depth = stack.depth.get() as usize;
let bytes = stack.elements[depth].bytes_total.get();
let count = stack.elements[depth].count_total.get();
let unsup_async = stack.elements[depth].unsupported_async.get();
stack.depth.set(stack.depth.get() - 1);
if !super::shared::is_alloc_self_enabled() {
let parent = stack.depth.get() as usize;
stack.elements[parent]
.bytes_total
.set(stack.elements[parent].bytes_total.get() + bytes);
stack.elements[parent]
.count_total
.set(stack.elements[parent].count_total.get() + count);
stack.elements[parent]
.unsupported_async
.set(stack.elements[parent].unsupported_async.get() | unsup_async);
}
(bytes, count, unsup_async)
})
};
super::core::ALLOCATIONS.with(|stack| {
stack.tracking_enabled.set(false);
});
let tid = if cross_thread { None } else { Some(self.tid) };
super::state::send_alloc_measurement_with_log(
self.name,
bytes_total,
count_total,
duration,
unsupported_async,
self.wrapper,
cross_thread,
tid,
Some(result_str),
);
super::core::ALLOCATIONS.with(|stack| {
stack.tracking_enabled.set(true);
});
}
}
impl Drop for MeasurementGuardWithLog {
#[inline]
fn drop(&mut self) {
if !self.finished {
let duration = self.start.elapsed();
let cross_thread = crate::tid::current_tid() != self.tid;
let (bytes_total, count_total, unsupported_async) =
if self.unsupported_async || cross_thread {
(0, 0, self.unsupported_async)
} else {
super::core::ALLOCATIONS.with(|stack| {
let depth = stack.depth.get() as usize;
let bytes = stack.elements[depth].bytes_total.get();
let count = stack.elements[depth].count_total.get();
let unsup_async = stack.elements[depth].unsupported_async.get();
stack.depth.set(stack.depth.get() - 1);
if !super::shared::is_alloc_self_enabled() {
let parent = stack.depth.get() as usize;
stack.elements[parent]
.bytes_total
.set(stack.elements[parent].bytes_total.get() + bytes);
stack.elements[parent]
.count_total
.set(stack.elements[parent].count_total.get() + count);
stack.elements[parent]
.unsupported_async
.set(stack.elements[parent].unsupported_async.get() | unsup_async);
}
(bytes, count, unsup_async)
})
};
super::core::ALLOCATIONS.with(|stack| {
stack.tracking_enabled.set(false);
});
let tid = if cross_thread { None } else { Some(self.tid) };
super::state::send_alloc_measurement_with_log(
self.name,
bytes_total,
count_total,
duration,
unsupported_async,
self.wrapper,
cross_thread,
tid,
None,
);
super::core::ALLOCATIONS.with(|stack| {
stack.tracking_enabled.set(true);
});
}
}
}