malloc_best_effort/
lib.rs1#![no_std]
2#![cfg_attr(docsrs, feature(doc_cfg))]
3
4#![doc = document_features::document_features!()]
56
57#[cfg(not(all(
58 target_os = "linux",
59 any(target_arch = "x86_64", target_arch = "aarch64",),
60 target_endian = "little"
61)))]
62mod mimalloc {
63 pub(crate) use mimalloc::MiMalloc as BEMallocImpl;
64
65 #[inline]
66 pub(crate) fn init_impl() {}
67}
68#[cfg(all(
69 target_os = "linux",
70 any(target_arch = "x86_64", target_arch = "aarch64",),
71 target_endian = "little"
72))]
73mod tcmalloc {
74 pub(crate) use tcmalloc_better::TCMalloc as BEMallocImpl;
75
76 #[cfg(feature = "std")]
77 #[cfg_attr(docsrs, doc(cfg(feature = "std")))]
78 #[inline]
79 pub(crate) fn init_impl() {
80 BEMallocImpl::process_background_actions_thread();
81 }
82
83 #[cfg(not(feature = "std"))]
84 #[cfg_attr(docsrs, doc(cfg(not(feature = "std"))))]
85 #[inline]
86 pub(crate) fn init_impl() {}
87}
88
89#[cfg(not(all(
90 target_os = "linux",
91 any(target_arch = "x86_64", target_arch = "aarch64",),
92 target_endian = "little"
93)))]
94use crate::mimalloc::BEMallocImpl;
95#[cfg(not(all(
96 target_os = "linux",
97 any(target_arch = "x86_64", target_arch = "aarch64",),
98 target_endian = "little"
99)))]
100use crate::mimalloc::init_impl;
101#[cfg(all(
102 target_os = "linux",
103 any(target_arch = "x86_64", target_arch = "aarch64",),
104 target_endian = "little"
105))]
106use crate::tcmalloc::BEMallocImpl;
107#[cfg(all(
108 target_os = "linux",
109 any(target_arch = "x86_64", target_arch = "aarch64",),
110 target_endian = "little"
111))]
112use crate::tcmalloc::init_impl;
113use core::alloc::{GlobalAlloc, Layout};
114
115pub struct BEMalloc {
118 alloc_impl: BEMallocImpl,
119}
120
121unsafe impl GlobalAlloc for BEMalloc {
122 #[inline]
123 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
124 unsafe { self.alloc_impl.alloc(layout) }
125 }
126
127 #[inline]
128 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
129 unsafe { self.alloc_impl.dealloc(ptr, layout) }
130 }
131
132 #[inline]
133 unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
134 unsafe { self.alloc_impl.alloc_zeroed(layout) }
135 }
136
137 #[inline]
138 unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
139 unsafe { self.alloc_impl.realloc(ptr, layout, new_size) }
140 }
141}
142
143impl Default for BEMalloc {
144 #[inline]
145 fn default() -> Self {
146 Self::new()
147 }
148}
149
150impl BEMalloc {
151 #[inline]
153 pub const fn new() -> Self {
154 Self {
155 alloc_impl: BEMallocImpl,
156 }
157 }
158 #[inline]
160 pub fn init() {
161 init_impl();
162 }
163}
164
165#[cfg(test)]
166mod tests {
167 use super::*;
168
169 #[test]
170 fn it_frees_allocated_memory() {
171 unsafe {
172 let layout = Layout::from_size_align(8, 8).unwrap();
173 let alloc = BEMalloc::new();
174
175 let ptr = alloc.alloc(layout);
176 alloc.dealloc(ptr, layout);
177 }
178 }
179
180 #[test]
181 fn it_frees_allocated_memory_with_init() {
182 unsafe {
183 let layout = Layout::from_size_align(8, 8).unwrap();
184 let alloc = BEMalloc::new();
185 BEMalloc::init();
186
187 let ptr = alloc.alloc(layout);
188 alloc.dealloc(ptr, layout);
189 }
190 }
191
192 #[test]
193 fn it_frees_allocated_big_memory() {
194 unsafe {
195 let layout = Layout::from_size_align(1 << 20, 32).unwrap();
196 let alloc = BEMalloc::new();
197
198 let ptr = alloc.alloc(layout);
199 alloc.dealloc(ptr, layout);
200 }
201 }
202
203 #[test]
204 fn it_frees_zero_allocated_memory() {
205 unsafe {
206 let layout = Layout::from_size_align(8, 8).unwrap();
207 let alloc = BEMalloc::new();
208
209 let ptr = alloc.alloc_zeroed(layout);
210 alloc.dealloc(ptr, layout);
211 }
212 }
213
214 #[test]
215 fn it_frees_zero_allocated_big_memory() {
216 unsafe {
217 let layout = Layout::from_size_align(1 << 20, 32).unwrap();
218 let alloc = BEMalloc::new();
219
220 let ptr = alloc.alloc_zeroed(layout);
221 alloc.dealloc(ptr, layout);
222 }
223 }
224
225 #[test]
226 fn it_frees_reallocated_memory() {
227 unsafe {
228 let layout = Layout::from_size_align(8, 8).unwrap();
229 let new_size = 16;
230 let new_layout = Layout::from_size_align(new_size, layout.align()).unwrap();
231 let alloc = BEMalloc::new();
232
233 let ptr = alloc.alloc(layout);
234 let ptr = alloc.realloc(ptr, layout, new_size);
235 alloc.dealloc(ptr, new_layout);
236 }
237 }
238
239 #[test]
240 fn it_frees_reallocated_big_memory() {
241 unsafe {
242 let layout = Layout::from_size_align(1 << 20, 32).unwrap();
243 let new_size = 2 << 20;
244 let new_layout = Layout::from_size_align(new_size, layout.align()).unwrap();
245 let alloc = BEMalloc::new();
246
247 let ptr = alloc.alloc(layout);
248 let ptr = alloc.realloc(ptr, layout, new_size);
249 alloc.dealloc(ptr, new_layout);
250 }
251 }
252}