system_mimalloc/lib.rs
1// SPDX-License-Identifier: MIT OR MIT-0
2//
3// Copyright © 2024 René Kijewski <crates.io@k6i.de>
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy of this
6// software and associated documentation files (the "Software"), to deal in the Software
7// without restriction, including without limitation the rights to use, copy, modify,
8// merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
9// permit persons to whom the Software is furnished to do so.
10//
11// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
12// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
13// PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
14// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
15// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
16// SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
17
18#![no_std]
19#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
20
21//! # `system-mimalloc` – use the system's shared mimalloc library as allocator
22//!
23//! [](https://github.com/Kijewski/system-mimalloc/actions/workflows/ci.yml)
24//! [](https://crates.io/crates/system-mimalloc)
25//! [](https://docs.rs/system-mimalloc/)
26//! 
27//! [](https://github.com/Kijewski/system-mimalloc/blob/v1.0.0/LICENSE.md "License: MIT-0")
28//!
29//! A drop-in global allocator using the system's shared [mimalloc](https://github.com/microsoft/mimalloc) library.
30//! Mimalloc is a general purpose, performance oriented allocator built by Microsoft.
31//!
32//! Probably only useful on Linux.
33//! Use <[crates.io/crates/mimalloc](https://crates.io/crates/mimalloc)> if you want to hard-link
34//! `mimalloc` to your program, to have more configuration options, and a higher platform compatibility.
35//!
36//! ## Usage
37//!
38//! Simply add this line to your `main.rs`:
39//!
40//! ```rust,ignore
41//! system_mimalloc::use_mimalloc!();
42//! ```
43//!
44//! # Requirements
45//!
46//! Make sure that `mimalloc` is installed, e.g.:
47//!
48//! ```sh
49//! sudo apt install libmimalloc-dev
50//! ```
51
52use core::alloc::{GlobalAlloc, Layout};
53use core::ffi::c_void;
54
55/// A [global allocator](GlobalAlloc) using the system's shared mimalloc library.
56///
57/// To use the allocator in your program, add either of the two code snippets to your `main.rs`:
58///
59/// ```rust,ignore
60/// system_mimalloc::use_mimalloc!();
61/// ```
62///
63/// ```rust,ignore
64/// use system_mimalloc::MiMalloc;
65///
66/// #[global_allocator]
67/// static GLOBAL: MiMalloc = MiMalloc;
68/// ```
69#[derive(Debug, Clone, Copy, PartialEq, Eq)]
70pub struct MiMalloc;
71
72/// Install [`MiMalloc`] as [global allocator](GlobalAlloc).
73///
74/// To use the allocator in your program, simply add this line to your `main.rs`:
75///
76/// ```rust,ignore
77/// system_mimalloc::use_mimalloc!();
78/// ```
79#[macro_export]
80macro_rules! use_mimalloc {
81 ($(,)?) => {
82 const _: () = {
83 #[global_allocator]
84 static GLOBAL: $crate::MiMalloc = $crate::MiMalloc;
85 };
86 };
87}
88
89#[allow(clippy::inline_always)]
90unsafe impl GlobalAlloc for MiMalloc {
91 #[inline(always)]
92 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
93 mi_malloc_aligned(layout.size(), layout.align()).cast()
94 }
95
96 #[inline(always)]
97 unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
98 mi_free(ptr.cast());
99 }
100
101 #[inline(always)]
102 unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
103 mi_zalloc_aligned(layout.size(), layout.align()).cast()
104 }
105
106 #[inline(always)]
107 unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
108 mi_realloc_aligned(ptr.cast(), new_size, layout.align()).cast()
109 }
110}
111
112#[link(name = "mimalloc")]
113extern "C" {
114 fn mi_malloc_aligned(size: usize, alignment: usize) -> *mut c_void;
115 fn mi_zalloc_aligned(size: usize, alignment: usize) -> *mut c_void;
116 fn mi_realloc_aligned(p: *mut c_void, newsize: usize, alignment: usize) -> *mut c_void;
117 fn mi_free(p: *mut c_void);
118}