Skip to main content

rustfs_mimalloc_sys/
lib.rs

1//! Low-level FFI bindings to [mimalloc](https://github.com/microsoft/mimalloc) V3 (v3.5.0).
2//!
3//! For a safe wrapper, use the `rustfs-mimalloc` crate.
4
5#![no_std]
6#![allow(non_camel_case_types)]
7
8// ── Type aliases ────────────────────────────────────────────────────────────
9
10pub use core::ffi::{c_char, c_int, c_long, c_void};
11
12pub type size_t = usize;
13
14// ── Opaque types ────────────────────────────────────────────────────────────
15
16#[repr(C)]
17pub struct mi_heap_t {
18    _opaque: [u8; 0],
19}
20
21#[repr(C)]
22pub struct mi_theap_t {
23    _opaque: [u8; 0],
24}
25
26/// Subprocess identifier. Opaque handle — do not access fields directly.
27#[repr(C)]
28#[derive(Clone, Copy)]
29pub struct mi_subproc_id_t {
30    _id: *mut c_void,
31}
32
33/// Arena identifier. Opaque handle.
34pub type mi_arena_id_t = *mut c_void;
35
36// ── Option enum ─────────────────────────────────────────────────────────────
37//
38// Kept in sync with mimalloc V3.5.0 `mi_option_e` in `mimalloc.h`.
39
40#[repr(C)]
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub enum mi_option_t {
43    mi_option_show_errors = 0,
44    mi_option_show_stats = 1,
45    mi_option_verbose = 2,
46    mi_option_arena_eager_commit = 4,
47    mi_option_purge_decommits = 5,
48    mi_option_allow_large_os_pages = 6,
49    mi_option_reserve_huge_os_pages = 7,
50    mi_option_reserve_huge_os_pages_at = 8,
51    mi_option_reserve_os_memory = 9,
52    mi_option_purge_delay = 15,
53    mi_option_use_numa_nodes = 16,
54    mi_option_disallow_os_alloc = 17,
55    mi_option_os_tag = 18,
56    mi_option_max_errors = 19,
57    mi_option_max_warnings = 20,
58    mi_option_destroy_on_exit = 22,
59    mi_option_arena_reserve = 23,
60    mi_option_arena_purge_mult = 24,
61    mi_option_disallow_arena_alloc = 26,
62    mi_option_retry_on_oom = 27,
63    mi_option_guarded_min = 29,
64    mi_option_guarded_max = 30,
65    mi_option_guarded_precise = 31,
66    mi_option_guarded_sample_rate = 32,
67    mi_option_guarded_sample_seed = 33,
68    mi_option_generic_collect = 34,
69    mi_option_page_reclaim_on_free = 35,
70    mi_option_page_full_retain = 36,
71    mi_option_page_max_candidates = 37,
72    mi_option_max_vabits = 38,
73    mi_option_pagemap_commit = 39,
74    mi_option_page_commit_on_demand = 40,
75    mi_option_page_max_reclaim = 41,
76    mi_option_page_cross_thread_max_reclaim = 42,
77    mi_option_allow_thp = 43,
78    mi_option_minimal_purge_size = 44,
79    mi_option_arena_max_object_size = 45,
80    mi_option_arena_is_numa_local = 46,
81}
82
83// ── Heap area (for visiting blocks) ─────────────────────────────────────────
84
85#[repr(C)]
86pub struct mi_heap_area_t {
87    pub blocks: *mut c_void,
88    pub reserved: size_t,
89    pub committed: size_t,
90    pub used: size_t,
91    pub block_size: size_t,
92    pub full_block_size: size_t,
93    pub reserved1: *mut c_void,
94}
95
96// ── Callback types ──────────────────────────────────────────────────────────
97
98pub type mi_output_fun = unsafe extern "C" fn(msg: *const c_char, arg: *mut c_void);
99pub type mi_error_fun = unsafe extern "C" fn(err: c_int, arg: *mut c_void);
100pub type mi_deferred_free_fun = unsafe extern "C" fn(force: bool, heartbeat: u64, arg: *mut c_void);
101pub type mi_block_visit_fun = unsafe extern "C" fn(
102    heap: *const mi_heap_t,
103    area: *const mi_heap_area_t,
104    block: *mut c_void,
105    block_size: size_t,
106    arg: *mut c_void,
107) -> bool;
108pub type mi_heap_visit_fun = unsafe extern "C" fn(heap: *mut mi_heap_t, arg: *mut c_void) -> bool;
109
110// ── Standard malloc interface ───────────────────────────────────────────────
111
112unsafe extern "C" {
113    pub fn mi_malloc(size: size_t) -> *mut c_void;
114    pub fn mi_calloc(count: size_t, size: size_t) -> *mut c_void;
115    pub fn mi_realloc(p: *mut c_void, newsize: size_t) -> *mut c_void;
116    pub fn mi_free(p: *mut c_void);
117    pub fn mi_strdup(s: *const c_char) -> *mut c_char;
118}
119
120// ── Extended allocation ─────────────────────────────────────────────────────
121
122unsafe extern "C" {
123    pub fn mi_malloc_small(size: size_t) -> *mut c_void;
124    pub fn mi_zalloc_small(size: size_t) -> *mut c_void;
125    pub fn mi_zalloc(size: size_t) -> *mut c_void;
126    pub fn mi_mallocn(count: size_t, size: size_t) -> *mut c_void;
127    pub fn mi_reallocn(p: *mut c_void, count: size_t, size: size_t) -> *mut c_void;
128    pub fn mi_usable_size(p: *const c_void) -> size_t;
129    pub fn mi_good_size(size: size_t) -> size_t;
130    pub fn mi_free_size(p: *mut c_void, size: size_t);
131    pub fn mi_free_small(p: *mut c_void);
132}
133
134// ── Aligned allocation ──────────────────────────────────────────────────────
135
136unsafe extern "C" {
137    pub fn mi_malloc_aligned(size: size_t, alignment: size_t) -> *mut c_void;
138    pub fn mi_zalloc_aligned(size: size_t, alignment: size_t) -> *mut c_void;
139    pub fn mi_calloc_aligned(count: size_t, size: size_t, alignment: size_t) -> *mut c_void;
140    pub fn mi_realloc_aligned(p: *mut c_void, newsize: size_t, alignment: size_t) -> *mut c_void;
141}
142
143// ── Process & thread lifecycle ──────────────────────────────────────────────
144
145unsafe extern "C" {
146    pub fn mi_collect(force: bool);
147    pub fn mi_thread_set_in_threadpool();
148    pub fn mi_version() -> c_int;
149    pub fn mi_process_info_print_out(out: Option<mi_output_fun>, arg: *mut c_void);
150    pub fn mi_process_info(
151        elapsed_msecs: *mut size_t,
152        user_msecs: *mut size_t,
153        system_msecs: *mut size_t,
154        current_rss: *mut size_t,
155        peak_rss: *mut size_t,
156        current_commit: *mut size_t,
157        peak_commit: *mut size_t,
158        page_faults: *mut size_t,
159    );
160}
161
162// ── Heaps ───────────────────────────────────────────────────────────────────
163
164unsafe extern "C" {
165    pub fn mi_heap_new() -> *mut mi_heap_t;
166    pub fn mi_heap_delete(heap: *mut mi_heap_t);
167    pub fn mi_heap_destroy(heap: *mut mi_heap_t);
168    pub fn mi_heap_collect(heap: *mut mi_heap_t, force: bool);
169    pub fn mi_heap_main() -> *mut mi_heap_t;
170    pub fn mi_heap_of(p: *const c_void) -> *mut mi_heap_t;
171    pub fn mi_heap_contains(heap: *const mi_heap_t, p: *const c_void) -> bool;
172
173    pub fn mi_heap_malloc(heap: *mut mi_heap_t, size: size_t) -> *mut c_void;
174    pub fn mi_heap_zalloc(heap: *mut mi_heap_t, size: size_t) -> *mut c_void;
175    pub fn mi_heap_calloc(heap: *mut mi_heap_t, count: size_t, size: size_t) -> *mut c_void;
176    pub fn mi_heap_realloc(heap: *mut mi_heap_t, p: *mut c_void, newsize: size_t) -> *mut c_void;
177    pub fn mi_heap_malloc_aligned(
178        heap: *mut mi_heap_t,
179        size: size_t,
180        alignment: size_t,
181    ) -> *mut c_void;
182}
183
184// ── Arena management ────────────────────────────────────────────────────────
185
186unsafe extern "C" {
187    pub fn mi_reserve_os_memory_ex(
188        size: size_t,
189        commit: bool,
190        allow_large: bool,
191        exclusive: bool,
192        arena_id: *mut mi_arena_id_t,
193    ) -> c_int;
194    pub fn mi_manage_os_memory_ex(
195        start: *mut c_void,
196        size: size_t,
197        is_committed: bool,
198        is_pinned: bool,
199        is_zero: bool,
200        numa_node: c_int,
201        exclusive: bool,
202        arena_id: *mut mi_arena_id_t,
203    ) -> bool;
204    pub fn mi_arena_min_alignment() -> size_t;
205    pub fn mi_arena_min_size() -> size_t;
206    pub fn mi_arena_max_object_size() -> size_t;
207    pub fn mi_heap_new_in_arena(arena_id: mi_arena_id_t) -> *mut mi_heap_t;
208}
209
210// ── Options ─────────────────────────────────────────────────────────────────
211
212unsafe extern "C" {
213    pub fn mi_option_is_enabled(option: mi_option_t) -> bool;
214    pub fn mi_option_enable(option: mi_option_t);
215    pub fn mi_option_disable(option: mi_option_t);
216    pub fn mi_option_get(option: mi_option_t) -> c_long;
217    pub fn mi_option_get_size(option: mi_option_t) -> size_t;
218    pub fn mi_option_set(option: mi_option_t, value: c_long);
219}
220
221// ── POSIX-compatible ────────────────────────────────────────────────────────
222
223unsafe extern "C" {
224    pub fn mi_posix_memalign(p: *mut *mut c_void, alignment: size_t, size: size_t) -> c_int;
225    pub fn mi_memalign(alignment: size_t, size: size_t) -> *mut c_void;
226    pub fn mi_malloc_size(p: *const c_void) -> size_t;
227    pub fn mi_malloc_usable_size(p: *const c_void) -> size_t;
228}
229
230// ── Statistics ──────────────────────────────────────────────────────────────
231
232unsafe extern "C" {
233    pub fn mi_stats_get_json(buf_size: size_t, buf: *mut c_char) -> *mut c_char;
234    pub fn mi_stats_print_out(out: Option<mi_output_fun>, arg: *mut c_void);
235    pub fn mi_stats_reset();
236    pub fn mi_heap_stats_get_json(
237        heap: *mut mi_heap_t,
238        buf_size: size_t,
239        buf: *mut c_char,
240    ) -> *mut c_char;
241    pub fn mi_heap_stats_print_out(
242        heap: *mut mi_heap_t,
243        out: Option<mi_output_fun>,
244        arg: *mut c_void,
245    );
246}