use std::alloc::{GlobalAlloc, Layout, System};
use std::cell::Cell;
thread_local! {
static COUNT: Cell<u64> = const { Cell::new(0) };
}
#[global_allocator]
static TALLY: Tally = Tally;
struct Tally;
unsafe impl GlobalAlloc for Tally {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
bump();
unsafe { System.alloc(layout) }
}
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
bump();
unsafe { System.alloc_zeroed(layout) }
}
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
bump();
unsafe { System.realloc(ptr, layout, new_size) }
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe { System.dealloc(ptr, layout) }
}
}
fn bump() {
let _ = COUNT.try_with(|c| c.set(c.get() + 1));
}
pub fn counted<T>(f: impl FnOnce() -> T) -> (T, u64) {
let before = COUNT.with(Cell::get);
let out = f();
let after = COUNT.with(Cell::get);
(out, after - before)
}