use std::alloc::GlobalAlloc;
use std::alloc::Layout;
use std::alloc::System;
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering;
use ark_api_ffi::entrypoints::core::AllocStats;
pub struct StatsAllocator {
cumul_alloc_count: AtomicUsize,
cumul_alloc_size: AtomicUsize,
cumul_free_count: AtomicUsize,
cumul_free_size: AtomicUsize,
stats: AllocStats,
}
#[global_allocator]
pub static mut GLOBAL_ALLOCATOR: StatsAllocator = StatsAllocator {
cumul_alloc_count: AtomicUsize::new(0),
cumul_alloc_size: AtomicUsize::new(0),
cumul_free_count: AtomicUsize::new(0),
cumul_free_size: AtomicUsize::new(0),
stats: AllocStats {
cumul_alloc_count: 0,
cumul_alloc_size: 0,
cumul_free_count: 0,
cumul_free_size: 0,
},
};
#[allow(dead_code)]
impl StatsAllocator {
pub fn copy_stats() {
unsafe {
GLOBAL_ALLOCATOR.stats = AllocStats {
cumul_alloc_count: GLOBAL_ALLOCATOR.cumul_alloc_count.load(Ordering::SeqCst) as u64,
cumul_alloc_size: GLOBAL_ALLOCATOR.cumul_alloc_size.load(Ordering::SeqCst) as u64,
cumul_free_count: GLOBAL_ALLOCATOR.cumul_free_count.load(Ordering::SeqCst) as u64,
cumul_free_size: GLOBAL_ALLOCATOR.cumul_free_size.load(Ordering::SeqCst) as u64,
}
}
}
}
unsafe impl GlobalAlloc for StatsAllocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
let _ = self.cumul_alloc_count.fetch_add(1, Ordering::SeqCst);
let _ = self
.cumul_alloc_size
.fetch_add(layout.size(), Ordering::SeqCst);
unsafe { System.alloc(layout) }
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
let _ = self.cumul_free_count.fetch_add(1, Ordering::SeqCst);
let _ = self
.cumul_free_size
.fetch_add(layout.size(), Ordering::SeqCst);
unsafe {
System.dealloc(ptr, layout);
}
}
}
#[no_mangle]
pub unsafe fn ark_alloc(size: usize, alignment: usize) -> *mut u8 {
let layout = std::alloc::Layout::from_size_align(size, alignment).unwrap();
unsafe { std::alloc::alloc(layout) }
}
#[no_mangle]
pub unsafe fn ark_free(ptr: *mut u8, size: usize, alignment: usize) {
let layout = std::alloc::Layout::from_size_align(size, alignment).unwrap();
unsafe {
std::alloc::dealloc(ptr, layout);
}
}
#[no_mangle]
#[doc(hidden)]
pub fn ark_get_alloc_stats() -> u32 {
StatsAllocator::copy_stats();
unsafe { &GLOBAL_ALLOCATOR.stats as *const AllocStats }.cast::<u8>() as usize as u32
}