#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![cfg_attr(not(feature = "std"), no_std)]
mod constants;
mod heap;
mod list;
mod page;
mod segment;
mod utils;
use core::alloc::{GlobalAlloc, Layout};
use heap::Heap;
#[derive(Default)]
pub struct Mimalloc<A: GlobalAlloc> {
heap: Heap,
os_alloc: A,
#[cfg(feature = "deferred_free")]
deferred_free_hook: Option<DeferredFreeHook<A>>,
}
#[cfg(feature = "deferred_free")]
pub mod deferred_free;
#[cfg(feature = "deferred_free")]
use deferred_free::*;
unsafe impl<A: GlobalAlloc> Send for Mimalloc<A> {}
impl<A: GlobalAlloc> Mimalloc<A> {
pub const fn with_os_allocator(os_alloc: A) -> Self {
Self {
heap: Heap::new(),
os_alloc,
#[cfg(feature = "deferred_free")]
deferred_free_hook: None,
}
}
#[cfg(feature = "deferred_free")]
pub const fn register_deferred_free(&mut self, hook: DeferredFreeHook<A>) {
self.deferred_free_hook = Some(hook);
}
pub fn collect(&mut self) {
self.heap.collect(&self.os_alloc);
}
pub unsafe fn alloc(&mut self, layout: Layout) -> *mut u8 {
self.heap.malloc_aligned(
layout.size(),
layout.align(),
&self.os_alloc,
#[cfg(feature = "deferred_free")]
self.deferred_free_hook,
)
}
pub unsafe fn dealloc(&mut self, ptr: *mut u8, _: Layout) {
self.heap.free(ptr, &self.os_alloc)
}
}
impl<A: GlobalAlloc> Drop for Mimalloc<A> {
fn drop(&mut self) {
self.collect();
}
}
#[cfg(feature = "mmap")]
mod mmap;
#[cfg(feature = "mmap")]
pub use mmap::{new_mimalloc_mmap, MimallocMmap, MmapAlloc};
#[cfg(all(not(docsrs), feature = "std_mutex", feature = "spin_mutex"))]
compile_error!("Only one of 'std_mutex' and 'spin_mutex' features can be enabled");
#[cfg(any(feature = "std_mutex", feature = "spin_mutex"))]
mod mutex;
#[cfg(any(feature = "std_mutex", feature = "spin_mutex"))]
pub use mutex::MimallocMutexWrapper;
#[cfg(all(feature = "mmap", any(feature = "std_mutex", feature = "spin_mutex")))]
pub type MimallocMmapMutex = MimallocMutexWrapper<MmapAlloc>;
#[cfg(all(feature = "mmap", any(feature = "std_mutex", feature = "spin_mutex")))]
pub const fn new_mimalloc_mmap_mutex() -> MimallocMmapMutex {
MimallocMutexWrapper::with_os_allocator(MmapAlloc)
}