#![warn(clippy::std_instead_of_alloc, clippy::std_instead_of_core)]
use cfg_if::cfg_if;
use core::alloc::{GlobalAlloc, Layout};
use core::fmt;
mod allocator;
mod allocator_stats;
mod metrics;
mod simple_allocator;
mod wrapped_allocator;
pub use allocator::Allocator;
pub use allocator_stats::{AllocatorStats, SimpleAllocatorStats, Statsable};
pub use simple_allocator::SimpleAllocator;
pub use wrapped_allocator::WrappedAllocator;
#[allow(dead_code)]
const fn config_mmap_heap_size() -> usize {
const DEFAULT_HEAP_SIZE: usize = 2097152;
const HEAP_SIZE_ARG: Option<&str> = option_env!("ALLOC_CAT_MMAP_HEAP_SIZE");
match HEAP_SIZE_ARG {
None => DEFAULT_HEAP_SIZE,
Some(s) => {
let mut acc: usize = 0;
let mut i = 0;
while i < s.len() {
acc = acc * 10 + (s.as_bytes()[i] - b'0') as usize;
i += 1;
}
acc
}
}
}
cfg_if! {
if #[cfg(any(test, not(feature = "system_allocator")))] {
mod mmap_heap;
pub use mmap_heap::MmapHeap;
}
}
cfg_if! {
if #[cfg(target_arch = "wasm32")] {
mod wasm_heap;
pub use wasm_heap::WasmHeap;
const HEAP: WasmHeap = WasmHeap {};
pub type AllocCat = Allocator<'static>;
pub static ALLOCATOR: AllocCat = Allocator::new(&HEAP);
} else if #[cfg(not(feature = "system_allocator"))] {
mod thread_safe_allocator;
pub use thread_safe_allocator::ThreadSafeAllocator;
static HEAP: MmapHeap = MmapHeap::new(config_mmap_heap_size());
pub type AllocCat = ThreadSafeAllocator<Allocator<'static>>;
static RAW_ALLOC: Allocator<'static> = Allocator::new(&HEAP);
pub static ALLOCATOR: AllocCat = ThreadSafeAllocator::new(&RAW_ALLOC);
} else {
pub type AllocCat = WrappedAllocator<std::alloc::System>;
pub static ALLOCATOR: AllocCat = WrappedAllocator::new(&std::alloc::System);
}
}
pub const PAGE_SIZE: usize = 64 * 1024;
pub trait Heap: fmt::Debug + fmt::Display {
fn heap_start(&self) -> usize;
fn heap_end(&self) -> usize;
fn heap_grow(&self, pages: usize) -> Option<*mut u8>;
}
unsafe impl GlobalAlloc for &AllocCat {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
unsafe { (*self).alloc(layout) }
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
unsafe { (*self).dealloc(ptr, layout) }
}
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
unsafe { (*self).alloc_zeroed(layout) }
}
unsafe fn realloc(&self, old_pointer: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
unsafe { (*self).realloc(old_pointer, layout, new_size) }
}
}