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()
39 .apply();
40});
41
42#[cfg(not(feature = "fast_allocator"))]
43use std::alloc::System;
44
45
46#[cfg(not(feature = "fast_allocator"))]
47static mut SAND: System = System;
48
49#[cfg(feature = "fast_allocator_options")]
50#[inline(always)]
51pub fn set_and_init_allocator_options(options_init_fn: Option<fn()>)
52{
53 if let Some(fx) = options_init_fn {
54 unsafe {
55 GLOBAL_ALLOC_OPTS = LazyLock::new(fx);
56 }
57 }
58
59 unsafe { *GLOBAL_ALLOC_OPTS }
60}
61
62#[inline(always)]
63pub unsafe fn direct_alloc(layout: Layout) -> *mut u8 {
64 #[cfg(feature = "fast_allocator_options")]
65 set_and_init_allocator_options(None);
66 SAND.alloc(layout)
67}
68
69#[inline(always)]
70pub unsafe fn direct_dealloc(ptr: *mut u8, layout: Layout) {
71 SAND.dealloc(ptr, layout)
72}
73
74pub struct DirectAllocator;
75
76unsafe impl Allocator for DirectAllocator {
77 #[inline(always)]
78 fn allocate(&self, layout: Layout) -> Result<NonNull<[u8]>, AllocError> {
79 let ptr = unsafe { direct_alloc(layout) };
80 let slice = unsafe { std::slice::from_raw_parts_mut(ptr, layout.size()) };
81 Ok(cast_to_nonnull::<[u8]>(slice))
82 }
83 #[inline(always)]
84 unsafe fn deallocate(&self, ptr: NonNull<u8>, layout: Layout) {
85 direct_dealloc(ptr.as_ptr(), layout);
86 }
87}
88
89pub static DIRECT_ALLOCATOR: DirectAllocator = DirectAllocator;
90