use std::collections::HashMap;
use std::sync::Weak;
use parking_lot::RwLock;
static MEMORY_REPORTERS: RwLock<Vec<MemoryReporterEntry>> = RwLock::new(Vec::new());
struct MemoryReporterEntry {
pub name: String,
pub reporter: Weak<dyn MemoryReporter>,
}
pub trait MemoryReporter: Send + Sync {
fn memory_allocated(&self) -> usize;
}
pub fn memory_reporters_allocated_total() -> usize {
let reporters = MEMORY_REPORTERS.read();
reporters
.iter()
.filter_map(|r| r.reporter.upgrade())
.map(|reporter| reporter.memory_allocated())
.sum()
}
pub fn memory_reporters_allocated_by_name() -> HashMap<String, usize> {
let reporters = MEMORY_REPORTERS.read();
let mut output = HashMap::new();
for r in reporters.iter() {
output.insert(
r.name.clone(),
r.reporter.upgrade().map(|v| v.memory_allocated()).unwrap_or(0),
);
}
output
}
pub fn register_memory_reporter(name: &str, reporter: Weak<dyn MemoryReporter>) {
let name = name.to_string();
let mut reporters = MEMORY_REPORTERS.write();
reporters.retain(|r| r.reporter.strong_count() > 0);
reporters.push(MemoryReporterEntry {
name,
reporter,
});
}
pub fn cleanup_memory_reporters() {
let mut reporters = MEMORY_REPORTERS.write();
reporters.retain(|r| r.reporter.strong_count() > 0);
}