alloc_cat 1.1.1

a simple allocator for small-to-tiny Wasm projects in rust
Documentation
use core::alloc::{GlobalAlloc, Layout};
use core::fmt;

use super::{AllocatorStats, Statsable};
use super::metrics::Metrics;


pub struct WrappedAllocator<A: GlobalAlloc + 'static> {
    pub inner: &'static A,
    metrics: Metrics,
}

unsafe impl<A: GlobalAlloc> Sync for WrappedAllocator<A> {}

impl<A: GlobalAlloc> fmt::Display for WrappedAllocator<A> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "SYSTEM")
    }
}

impl<A: GlobalAlloc> WrappedAllocator<A> {
    pub const fn new(inner: &'static A) -> WrappedAllocator<A> {
        WrappedAllocator { inner, metrics: Metrics::new() }
    }
}

unsafe impl<A: GlobalAlloc> GlobalAlloc for WrappedAllocator<A> {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        self.metrics.add(layout);
        unsafe { self.inner.alloc(layout) }
    }

    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
        self.metrics.subtract(layout);
        unsafe { self.inner.dealloc(ptr, layout) }
    }

    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
        self.metrics.add(layout);
        unsafe { self.inner.alloc_zeroed(layout) }
    }

    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
        self.metrics.subtract(layout);
        self.metrics.add(Layout::from_size_align(new_size, layout.align()).unwrap());
        unsafe { self.inner.realloc(ptr, layout, new_size) }
    }
}

impl<A: GlobalAlloc> Statsable for WrappedAllocator<A> {
    fn get_stats(&self) -> AllocatorStats {
        let mut stats = AllocatorStats::default();
        self.metrics.get_stats(&mut stats);
        stats
    }

    fn reset_trip(&self) {
        self.metrics.reset_trip();
    }
}