#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub struct MemoryUse {
pub resident: Option<u64>,
pub counted: Option<u64>,
}
impl MemoryUse {
#[inline]
pub fn capture() -> Self {
Self {
resident: bytes_resident(),
counted: crate::accounting_allocator::global_allocs().map(|c| c.size as _),
}
}
#[inline]
pub fn used(&self) -> Option<u64> {
self.counted.or(self.resident)
}
}
impl std::ops::Mul<f32> for MemoryUse {
type Output = Self;
fn mul(self, factor: f32) -> Self::Output {
Self {
resident: self.resident.map(|v| (v as f32 * factor) as u64),
counted: self.counted.map(|v| (v as f32 * factor) as u64),
}
}
}
impl std::ops::Sub for MemoryUse {
type Output = Self;
#[inline]
fn sub(self, rhs: Self) -> Self::Output {
fn sub(a: Option<u64>, b: Option<u64>) -> Option<u64> {
Some(a?.saturating_sub(b?))
}
Self {
resident: sub(self.resident, rhs.resident),
counted: sub(self.counted, rhs.counted),
}
}
}
#[cfg(not(target_arch = "wasm32"))]
fn bytes_resident() -> Option<u64> {
memory_stats::memory_stats().map(|usage| usage.physical_mem as u64)
}
#[cfg(target_arch = "wasm32")]
fn bytes_resident() -> Option<u64> {
None
}