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//! [![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/Kijewski/system-mimalloc/ci.yml?branch=main&style=flat-square&logo=github&logoColor=white "GitHub Workflow Status")](https://github.com/Kijewski/system-mimalloc/actions/workflows/ci.yml)
24//! [![Crates.io](https://img.shields.io/crates/v/system-mimalloc?logo=rust&style=flat-square "Crates.io")](https://crates.io/crates/system-mimalloc)
25//! [![docs.rs](https://img.shields.io/docsrs/system-mimalloc?logo=docsdotrs&style=flat-square&logoColor=white "docs.rs")](https://docs.rs/system-mimalloc/)
26//! ![Minimum supported Rust version: 1.38](https://img.shields.io/badge/rustc-1.38+-informational?logo=rust&style=flat-square "Minimum Supported Rust Version: 1.38")
27//! [![License: MIT-0](https://img.shields.io/badge/license-MIT--0-informational?logo=apache&style=flat-square)](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 &lt;[crates.io/crates/mimalloc](https://crates.io/crates/mimalloc)&gt; 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}