mimalloc/
lib.rs

1// Copyright 2019 Octavian Oncescu
2
3#![no_std]
4
5//! A drop-in global allocator wrapper around the [mimalloc](https://github.com/microsoft/mimalloc) allocator.
6//! Mimalloc is a general purpose, performance oriented allocator built by Microsoft.
7//!
8//! ## Usage
9//! ```rust,ignore
10//! use mimalloc::MiMalloc;
11//!
12//! #[global_allocator]
13//! static GLOBAL: MiMalloc = MiMalloc;
14//! ```
15//!
16//! ## Usage with secure mode
17//! Using secure mode adds guard pages,
18//! randomized allocation, encrypted free lists, etc. The performance penalty is usually
19//! around 10% according to [mimalloc's](https://github.com/microsoft/mimalloc)
20//! own benchmarks.
21//!
22//! To enable secure mode, put in `Cargo.toml`:
23//! ```rust,ignore
24//! [dependencies]
25//! mimalloc = { version = "*", features = ["secure"] }
26//! ```
27
28extern crate libmimalloc_sys as ffi;
29
30#[cfg(feature = "extended")]
31mod extended;
32
33use core::alloc::{GlobalAlloc, Layout};
34use core::ffi::c_void;
35use ffi::*;
36
37/// Drop-in mimalloc global allocator.
38///
39/// ## Usage
40/// ```rust,ignore
41/// use mimalloc::MiMalloc;
42///
43/// #[global_allocator]
44/// static GLOBAL: MiMalloc = MiMalloc;
45/// ```
46pub struct MiMalloc;
47
48unsafe impl GlobalAlloc for MiMalloc {
49    #[inline]
50    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
51        mi_malloc_aligned(layout.size(), layout.align()) as *mut u8
52    }
53
54    #[inline]
55    unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
56        mi_zalloc_aligned(layout.size(), layout.align()) as *mut u8
57    }
58
59    #[inline]
60    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
61        mi_free(ptr as *mut c_void);
62    }
63
64    #[inline]
65    unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
66        mi_realloc_aligned(ptr as *mut c_void, new_size, layout.align()) as *mut u8
67    }
68}
69
70#[cfg(test)]
71mod tests {
72    use super::*;
73
74    #[test]
75    fn it_frees_allocated_memory() {
76        unsafe {
77            let layout = Layout::from_size_align(8, 8).unwrap();
78            let alloc = MiMalloc;
79
80            let ptr = alloc.alloc(layout);
81            alloc.dealloc(ptr, layout);
82        }
83    }
84
85    #[test]
86    fn it_frees_allocated_big_memory() {
87        unsafe {
88            let layout = Layout::from_size_align(1 << 20, 32).unwrap();
89            let alloc = MiMalloc;
90
91            let ptr = alloc.alloc(layout);
92            alloc.dealloc(ptr, layout);
93        }
94    }
95
96    #[test]
97    fn it_frees_zero_allocated_memory() {
98        unsafe {
99            let layout = Layout::from_size_align(8, 8).unwrap();
100            let alloc = MiMalloc;
101
102            let ptr = alloc.alloc_zeroed(layout);
103            alloc.dealloc(ptr, layout);
104        }
105    }
106
107    #[test]
108    fn it_frees_zero_allocated_big_memory() {
109        unsafe {
110            let layout = Layout::from_size_align(1 << 20, 32).unwrap();
111            let alloc = MiMalloc;
112
113            let ptr = alloc.alloc_zeroed(layout);
114            alloc.dealloc(ptr, layout);
115        }
116    }
117
118    #[test]
119    fn it_frees_reallocated_memory() {
120        unsafe {
121            let layout = Layout::from_size_align(8, 8).unwrap();
122            let alloc = MiMalloc;
123
124            let ptr = alloc.alloc(layout);
125            let ptr = alloc.realloc(ptr, layout, 16);
126            alloc.dealloc(ptr, layout);
127        }
128    }
129
130    #[test]
131    fn it_frees_reallocated_big_memory() {
132        unsafe {
133            let layout = Layout::from_size_align(1 << 20, 32).unwrap();
134            let alloc = MiMalloc;
135
136            let ptr = alloc.alloc(layout);
137            let ptr = alloc.realloc(ptr, layout, 2 << 20);
138            alloc.dealloc(ptr, layout);
139        }
140    }
141}