malloc_best_effort/
lib.rs1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3
4#![doc = document_features::document_features!()]
17
18#[cfg(not(all(
19 target_os = "linux",
20 any(target_arch = "x86_64", target_arch = "aarch64")
21)))]
22mod mimalloc {
23 pub(crate) use mimalloc::MiMalloc as BEMallocImpl;
24
25 #[inline]
26 pub(crate) fn init_impl() {}
27}
28#[cfg(all(
29 target_os = "linux",
30 any(target_arch = "x86_64", target_arch = "aarch64")
31))]
32mod tcmalloc {
33 pub(crate) use tcmalloc_better::TCMalloc as BEMallocImpl;
34
35 #[cfg(feature = "std")]
36 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
37 #[inline]
38 pub(crate) fn init_impl() {
39 BEMallocImpl::process_background_actions_thread();
40 }
41
42 #[cfg(not(feature = "std"))]
43 #[cfg_attr(docsrs, doc(cfg(not(feature = "std"))))]
44 #[inline]
45 pub(crate) fn init_impl() {}
46}
47
48#[cfg(not(all(
49 target_os = "linux",
50 any(target_arch = "x86_64", target_arch = "aarch64")
51)))]
52use crate::mimalloc::BEMallocImpl;
53#[cfg(not(all(
54 target_os = "linux",
55 any(target_arch = "x86_64", target_arch = "aarch64")
56)))]
57use crate::mimalloc::init_impl;
58#[cfg(all(
59 target_os = "linux",
60 any(target_arch = "x86_64", target_arch = "aarch64")
61))]
62use crate::tcmalloc::BEMallocImpl;
63#[cfg(all(
64 target_os = "linux",
65 any(target_arch = "x86_64", target_arch = "aarch64")
66))]
67use crate::tcmalloc::init_impl;
68use core::alloc::{GlobalAlloc, Layout};
69
70pub struct BEMalloc {
73 alloc_impl: BEMallocImpl,
74}
75
76unsafe impl GlobalAlloc for BEMalloc {
77 #[inline]
78 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
79 unsafe { self.alloc_impl.alloc(layout) }
80 }
81
82 #[inline]
83 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
84 unsafe { self.alloc_impl.dealloc(ptr, layout) }
85 }
86
87 #[inline]
88 unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
89 unsafe { self.alloc_impl.alloc_zeroed(layout) }
90 }
91
92 #[inline]
93 unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
94 unsafe { self.alloc_impl.realloc(ptr, layout, new_size) }
95 }
96}
97
98impl Default for BEMalloc {
99 #[inline]
100 fn default() -> Self {
101 Self::new()
102 }
103}
104
105impl BEMalloc {
106 #[inline]
108 pub const fn new() -> Self {
109 Self {
110 alloc_impl: BEMallocImpl,
111 }
112 }
113 #[inline]
115 pub fn init() {
116 init_impl();
117 }
118}
119
120#[cfg(test)]
121mod tests {
122 use super::*;
123
124 #[test]
125 fn it_frees_allocated_memory() {
126 unsafe {
127 let layout = Layout::from_size_align(8, 8).unwrap();
128 let alloc = BEMalloc::new();
129
130 let ptr = alloc.alloc(layout);
131 alloc.dealloc(ptr, layout);
132 }
133 }
134
135 #[test]
136 fn it_frees_allocated_big_memory() {
137 unsafe {
138 let layout = Layout::from_size_align(1 << 20, 32).unwrap();
139 let alloc = BEMalloc::new();
140
141 let ptr = alloc.alloc(layout);
142 alloc.dealloc(ptr, layout);
143 }
144 }
145
146 #[test]
147 fn it_frees_zero_allocated_memory() {
148 unsafe {
149 let layout = Layout::from_size_align(8, 8).unwrap();
150 let alloc = BEMalloc::new();
151
152 let ptr = alloc.alloc_zeroed(layout);
153 alloc.dealloc(ptr, layout);
154 }
155 }
156
157 #[test]
158 fn it_frees_zero_allocated_big_memory() {
159 unsafe {
160 let layout = Layout::from_size_align(1 << 20, 32).unwrap();
161 let alloc = BEMalloc::new();
162
163 let ptr = alloc.alloc_zeroed(layout);
164 alloc.dealloc(ptr, layout);
165 }
166 }
167
168 #[test]
169 fn it_frees_reallocated_memory() {
170 unsafe {
171 let layout = Layout::from_size_align(8, 8).unwrap();
172 let new_size = 16;
173 let new_layout = Layout::from_size_align(new_size, layout.align()).unwrap();
174 let alloc = BEMalloc::new();
175
176 let ptr = alloc.alloc(layout);
177 let ptr = alloc.realloc(ptr, layout, new_size);
178 alloc.dealloc(ptr, new_layout);
179 }
180 }
181
182 #[test]
183 fn it_frees_reallocated_big_memory() {
184 unsafe {
185 let layout = Layout::from_size_align(1 << 20, 32).unwrap();
186 let new_size = 2 << 20;
187 let new_layout = Layout::from_size_align(new_size, layout.align()).unwrap();
188 let alloc = BEMalloc::new();
189
190 let ptr = alloc.alloc(layout);
191 let ptr = alloc.realloc(ptr, layout, new_size);
192 alloc.dealloc(ptr, new_layout);
193 }
194 }
195}