use std::alloc::{GlobalAlloc, Layout, System};
use std::sync::atomic::{AtomicUsize, Ordering::Relaxed};
pub static LIVE: AtomicUsize = AtomicUsize::new(0);
pub static PEAK: AtomicUsize = AtomicUsize::new(0);
pub static COUNT: AtomicUsize = AtomicUsize::new(0);
pub struct Counting;
unsafe impl GlobalAlloc for Counting {
unsafe fn alloc(&self, l: Layout) -> *mut u8 {
let n = LIVE.fetch_add(l.size(), Relaxed) + l.size();
PEAK.fetch_max(n, Relaxed);
COUNT.fetch_add(1, Relaxed);
unsafe { System.alloc(l) }
}
unsafe fn dealloc(&self, p: *mut u8, l: Layout) {
LIVE.fetch_sub(l.size(), Relaxed);
unsafe { System.dealloc(p, l) }
}
unsafe fn realloc(&self, p: *mut u8, l: Layout, new: usize) -> *mut u8 {
if new >= l.size() {
let n = LIVE.fetch_add(new - l.size(), Relaxed) + new - l.size();
PEAK.fetch_max(n, Relaxed);
} else {
LIVE.fetch_sub(l.size() - new, Relaxed);
}
COUNT.fetch_add(1, Relaxed);
unsafe { System.realloc(p, l, new) }
}
}
#[global_allocator]
static ALLOC: Counting = Counting;
pub fn mb(n: usize) -> f64 {
n as f64 / 1048576.0
}