1use std::alloc::{AllocError, Allocator};
21use std::alloc::{GlobalAlloc, Layout};
22use std::sync::LazyLock;
23
24use crate::mem::cast_to_nonnull;
25use std::ptr::NonNull;
26
27#[cfg(feature = "fast_allocator")]
28use mimalloc::MiMalloc;
29
30#[cfg(feature = "fast_allocator")]
31static mut SAND: MiMalloc = MiMalloc;
32
33#[cfg(feature = "fast_allocator_options")]
34use crate::mem::alloc_opts::MiMallocOpts;
35
36#[cfg(feature = "fast_allocator_options")]
37static mut GLOBAL_ALLOC_OPTS: LazyLock<()> = LazyLock::new(|| {
38 MiMallocOpts::builder().apply();
39});
40
41#[cfg(not(feature = "fast_allocator"))]
42use std::alloc::System;
43
44#[cfg(not(feature = "fast_allocator"))]
45static mut SAND: System = System;
46
47#[cfg(feature = "fast_allocator_options")]
48#[inline(always)]
49pub fn set_and_init_allocator_options(options_init_fn: Option<fn()>)
50{
51 if let Some(fx) = options_init_fn {
52 unsafe {
53 GLOBAL_ALLOC_OPTS = LazyLock::new(fx);
54 }
55 }
56
57 unsafe { *GLOBAL_ALLOC_OPTS }
58}
59
60#[inline(always)]
61pub unsafe fn direct_alloc(layout: Layout) -> *mut u8 {
62 #[cfg(feature = "fast_allocator_options")]
63 set_and_init_allocator_options(None);
64 SAND.alloc(layout)
65}
66
67#[inline(always)]
68pub unsafe fn direct_dealloc(ptr: *mut u8, layout: Layout) {
69 SAND.dealloc(ptr, layout)
70}
71
72pub struct DirectAllocator;
73
74unsafe impl Allocator for DirectAllocator {
75 #[inline(always)]
76 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
77 let ptr = unsafe { direct_alloc(layout) };
78 let slice = unsafe { std::slice::from_raw_parts_mut(ptr, layout.size()) };
79 Ok(cast_to_nonnull::<[u8]>(slice))
80 }
81 #[inline(always)]
82 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
83 direct_dealloc(ptr.as_ptr(), layout);
84 }
85}
86
87pub static DIRECT_ALLOCATOR: DirectAllocator = DirectAllocator;
88