1#![no_std]
6#![allow(non_camel_case_types)]
7
8pub use core::ffi::{c_char, c_int, c_long, c_void};
11
12pub type size_t = usize;
13
14pub const MI_SMALL_WSIZE_MAX: size_t = 128;
18
19pub const MI_SMALL_SIZE_MAX: size_t = MI_SMALL_WSIZE_MAX * core::mem::size_of::<size_t>();
21
22pub const MI_PROFILE_SAMPLE_DATA_MAX_SIZE: size_t = 1024;
24
25#[repr(C)]
28pub struct mi_heap_t {
29 _opaque: [u8; 0],
30}
31
32#[repr(C)]
33pub struct mi_theap_t {
34 _opaque: [u8; 0],
35}
36
37#[repr(C)]
39#[derive(Clone, Copy)]
40pub struct mi_subproc_id_t {
41 _id: *mut c_void,
42}
43
44pub type mi_arena_id_t = *mut c_void;
46
47#[repr(C)]
52#[derive(Debug, Clone, Copy, PartialEq, Eq)]
53pub enum mi_option_t {
54 mi_option_show_errors = 0,
55 mi_option_show_stats = 1,
56 mi_option_verbose = 2,
57 mi_option_arena_eager_commit = 4,
58 mi_option_purge_decommits = 5,
59 mi_option_allow_large_os_pages = 6,
60 mi_option_reserve_huge_os_pages = 7,
61 mi_option_reserve_huge_os_pages_at = 8,
62 mi_option_reserve_os_memory = 9,
63 mi_option_purge_delay = 15,
64 mi_option_use_numa_nodes = 16,
65 mi_option_disallow_os_alloc = 17,
66 mi_option_os_tag = 18,
67 mi_option_max_errors = 19,
68 mi_option_max_warnings = 20,
69 mi_option_destroy_on_exit = 22,
70 mi_option_arena_reserve = 23,
71 mi_option_arena_purge_mult = 24,
72 mi_option_disallow_arena_alloc = 26,
73 mi_option_retry_on_oom = 27,
74 mi_option_guarded_min = 29,
75 mi_option_guarded_max = 30,
76 mi_option_guarded_precise = 31,
77 mi_option_guarded_sample_rate = 32,
78 mi_option_guarded_sample_seed = 33,
79 mi_option_generic_collect = 34,
80 mi_option_page_reclaim_on_free = 35,
81 mi_option_page_full_retain = 36,
82 mi_option_page_max_candidates = 37,
83 mi_option_max_vabits = 38,
84 mi_option_pagemap_commit = 39,
85 mi_option_page_commit_on_demand = 40,
86 mi_option_page_max_reclaim = 41,
87 mi_option_page_cross_thread_max_reclaim = 42,
88 mi_option_allow_thp = 43,
89 mi_option_minimal_purge_size = 44,
90 mi_option_arena_max_object_size = 45,
91 mi_option_arena_is_numa_local = 46,
92 mi_option_collect_merges_stats = 47,
93}
94
95#[repr(C)]
98pub struct mi_heap_area_t {
99 pub blocks: *mut c_void,
100 pub reserved: size_t,
101 pub committed: size_t,
102 pub used: size_t,
103 pub block_size: size_t,
104 pub full_block_size: size_t,
105 pub reserved1: *mut c_void,
106}
107
108pub type mi_output_fun = unsafe extern "C" fn(msg: *const c_char, arg: *mut c_void);
111pub type mi_error_fun = unsafe extern "C" fn(err: c_int, arg: *mut c_void);
112pub type mi_deferred_free_fun = unsafe extern "C" fn(force: bool, heartbeat: u64, arg: *mut c_void);
113pub type mi_profiler_on_alloc_fun = unsafe extern "C" fn(
114 profiler: *mut mi_profiler_t,
115 profiler_data: *mut mi_profiler_sample_data_t,
116 ptr: *mut c_void,
117 requested_size: size_t,
118 bytes_sample_rate: size_t,
119 bytes_since_last_sample: u64,
120 heap: *const mi_heap_t,
121) -> size_t;
122pub type mi_profiler_on_realloc_inplace_fun = unsafe extern "C" fn(
123 profiler: *mut mi_profiler_t,
124 profiler_data: *mut mi_profiler_sample_data_t,
125 ptr: *mut c_void,
126 old_size: size_t,
127 heap: *const mi_heap_t,
128) -> size_t;
129pub type mi_profiler_on_free_fun = unsafe extern "C" fn(
130 profiler: *mut mi_profiler_t,
131 profiler_data: *mut mi_profiler_sample_data_t,
132 ptr: *mut c_void,
133 heap: *const mi_heap_t,
134);
135pub type mi_block_visit_fun = unsafe extern "C" fn(
136 heap: *const mi_heap_t,
137 area: *const mi_heap_area_t,
138 block: *mut c_void,
139 block_size: size_t,
140 arg: *mut c_void,
141) -> bool;
142pub type mi_heap_visit_fun = unsafe extern "C" fn(heap: *mut mi_heap_t, arg: *mut c_void) -> bool;
143
144#[repr(C)]
147pub struct mi_profiler_sample_data_t {
148 pub user_data_size: size_t,
149 pub user_data: [*mut c_void; 1],
150}
151
152#[repr(C)]
154pub struct mi_profiler_t {
155 pub reserved: *mut c_void,
156 pub sample_data_size: size_t,
157 pub initial_sample_rate: size_t,
158 pub on_alloc: Option<mi_profiler_on_alloc_fun>,
159 pub on_free: Option<mi_profiler_on_free_fun>,
160 pub on_realloc_inplace: Option<mi_profiler_on_realloc_inplace_fun>,
161}
162
163unsafe extern "C" {
166 pub fn mi_malloc(size: size_t) -> *mut c_void;
167 pub fn mi_calloc(count: size_t, size: size_t) -> *mut c_void;
168 pub fn mi_realloc(p: *mut c_void, newsize: size_t) -> *mut c_void;
169 pub fn mi_free(p: *mut c_void);
170 pub fn mi_strdup(s: *const c_char) -> *mut c_char;
171}
172
173unsafe extern "C" {
176 pub fn mi_malloc_small(size: size_t) -> *mut c_void;
177 pub fn mi_zalloc_small(size: size_t) -> *mut c_void;
178 pub fn mi_wmalloc_small(wsize: size_t) -> *mut c_void;
179 pub fn mi_wzalloc_small(wsize: size_t) -> *mut c_void;
180 pub fn mi_zalloc(size: size_t) -> *mut c_void;
181 pub fn mi_mallocn(count: size_t, size: size_t) -> *mut c_void;
182 pub fn mi_reallocn(p: *mut c_void, count: size_t, size: size_t) -> *mut c_void;
183 pub fn mi_usable_size(p: *const c_void) -> size_t;
184 pub fn mi_good_size(size: size_t) -> size_t;
185 pub fn mi_free_size(p: *mut c_void, size: size_t);
186 pub fn mi_free_small(p: *mut c_void);
187 pub fn mi_free_small_nonnull(p: *mut c_void);
188}
189
190#[inline]
192pub const fn mi_wsize_from_size(size: size_t) -> size_t {
193 size.div_ceil(core::mem::size_of::<size_t>())
194}
195
196#[inline]
205pub unsafe fn mi_malloc_csize(size: size_t) -> *mut c_void {
206 if size <= MI_SMALL_SIZE_MAX {
207 unsafe { mi_wmalloc_small(mi_wsize_from_size(size)) }
208 } else {
209 unsafe { mi_malloc(size) }
210 }
211}
212
213#[inline]
222pub unsafe fn mi_zalloc_csize(size: size_t) -> *mut c_void {
223 if size <= MI_SMALL_SIZE_MAX {
224 unsafe { mi_wzalloc_small(mi_wsize_from_size(size)) }
225 } else {
226 unsafe { mi_zalloc(size) }
227 }
228}
229
230#[inline]
239pub unsafe fn mi_free_csize(p: *mut c_void, size: size_t) {
240 if size <= MI_SMALL_SIZE_MAX {
241 unsafe { mi_free_small(p) };
242 } else {
243 unsafe { mi_free(p) };
244 }
245}
246
247#[inline]
256pub unsafe fn mi_free_csize_nonnull(p: *mut c_void, size: size_t) {
257 if size <= MI_SMALL_SIZE_MAX {
258 unsafe { mi_free_small_nonnull(p) };
259 } else {
260 unsafe { mi_free(p) };
261 }
262}
263
264unsafe extern "C" {
267 pub fn mi_malloc_aligned(size: size_t, alignment: size_t) -> *mut c_void;
268 pub fn mi_zalloc_aligned(size: size_t, alignment: size_t) -> *mut c_void;
269 pub fn mi_calloc_aligned(count: size_t, size: size_t, alignment: size_t) -> *mut c_void;
270 pub fn mi_realloc_aligned(p: *mut c_void, newsize: size_t, alignment: size_t) -> *mut c_void;
271}
272
273unsafe extern "C" {
276 pub fn mi_collect(force: bool);
277 pub fn mi_thread_set_in_threadpool();
278 pub fn mi_version() -> c_int;
279 pub fn mi_process_info_print_out(out: Option<mi_output_fun>, arg: *mut c_void);
280 pub fn mi_process_info(
281 elapsed_msecs: *mut size_t,
282 user_msecs: *mut size_t,
283 system_msecs: *mut size_t,
284 current_rss: *mut size_t,
285 peak_rss: *mut size_t,
286 current_commit: *mut size_t,
287 peak_commit: *mut size_t,
288 page_faults: *mut size_t,
289 );
290}
291
292unsafe extern "C" {
295 pub fn mi_heap_new() -> *mut mi_heap_t;
296 pub fn mi_heap_delete(heap: *mut mi_heap_t);
297 pub fn mi_heap_destroy(heap: *mut mi_heap_t);
298 pub fn mi_heap_collect(heap: *mut mi_heap_t, force: bool);
299 pub fn mi_heap_main() -> *mut mi_heap_t;
300 pub fn mi_heap_of(p: *const c_void) -> *mut mi_heap_t;
301 pub fn mi_heap_contains(heap: *const mi_heap_t, p: *const c_void) -> bool;
302 pub fn mi_heap_theap(heap: *mut mi_heap_t) -> *mut mi_theap_t;
303
304 pub fn mi_heap_malloc(heap: *mut mi_heap_t, size: size_t) -> *mut c_void;
305 pub fn mi_heap_zalloc(heap: *mut mi_heap_t, size: size_t) -> *mut c_void;
306 pub fn mi_heap_calloc(heap: *mut mi_heap_t, count: size_t, size: size_t) -> *mut c_void;
307 pub fn mi_heap_realloc(heap: *mut mi_heap_t, p: *mut c_void, newsize: size_t) -> *mut c_void;
308 pub fn mi_heap_malloc_aligned(
309 heap: *mut mi_heap_t,
310 size: size_t,
311 alignment: size_t,
312 ) -> *mut c_void;
313}
314
315unsafe extern "C" {
318 pub fn mi_theap_malloc(theap: *mut mi_theap_t, size: size_t) -> *mut c_void;
319 pub fn mi_theap_zalloc(theap: *mut mi_theap_t, size: size_t) -> *mut c_void;
320 pub fn mi_theap_malloc_small(theap: *mut mi_theap_t, size: size_t) -> *mut c_void;
321 pub fn mi_theap_zalloc_small(theap: *mut mi_theap_t, size: size_t) -> *mut c_void;
322 pub fn mi_theap_wmalloc_small(theap: *mut mi_theap_t, wsize: size_t) -> *mut c_void;
323 pub fn mi_theap_wzalloc_small(theap: *mut mi_theap_t, wsize: size_t) -> *mut c_void;
324}
325
326#[inline]
335pub unsafe fn mi_theap_malloc_csize(theap: *mut mi_theap_t, size: size_t) -> *mut c_void {
336 if size <= MI_SMALL_SIZE_MAX {
337 unsafe { mi_theap_wmalloc_small(theap, mi_wsize_from_size(size)) }
338 } else {
339 unsafe { mi_theap_malloc(theap, size) }
340 }
341}
342
343#[inline]
352pub unsafe fn mi_theap_zalloc_csize(theap: *mut mi_theap_t, size: size_t) -> *mut c_void {
353 if size <= MI_SMALL_SIZE_MAX {
354 unsafe { mi_theap_wzalloc_small(theap, mi_wsize_from_size(size)) }
355 } else {
356 unsafe { mi_theap_zalloc(theap, size) }
357 }
358}
359
360unsafe extern "C" {
363 pub fn mi_reserve_os_memory_ex(
364 size: size_t,
365 commit: bool,
366 allow_large: bool,
367 exclusive: bool,
368 arena_id: *mut mi_arena_id_t,
369 ) -> c_int;
370 pub fn mi_manage_os_memory_ex(
371 start: *mut c_void,
372 size: size_t,
373 is_committed: bool,
374 is_pinned: bool,
375 is_zero: bool,
376 numa_node: c_int,
377 exclusive: bool,
378 arena_id: *mut mi_arena_id_t,
379 ) -> bool;
380 pub fn mi_arena_min_alignment() -> size_t;
381 pub fn mi_arena_min_size() -> size_t;
382 pub fn mi_arena_max_object_size() -> size_t;
383 pub fn mi_heap_new_in_arena(arena_id: mi_arena_id_t) -> *mut mi_heap_t;
384}
385
386unsafe extern "C" {
389 pub fn mi_option_is_enabled(option: mi_option_t) -> bool;
390 pub fn mi_option_enable(option: mi_option_t);
391 pub fn mi_option_disable(option: mi_option_t);
392 pub fn mi_option_get(option: mi_option_t) -> c_long;
393 pub fn mi_option_get_size(option: mi_option_t) -> size_t;
394 pub fn mi_option_set(option: mi_option_t, value: c_long);
395}
396
397unsafe extern "C" {
400 pub fn mi_heap_profile(heap: *mut mi_heap_t, profiler: *mut mi_profiler_t) -> bool;
401 pub fn mi_heap_profile_disable(heap: *mut mi_heap_t);
402 pub fn mi_subproc_profile(subproc_id: mi_subproc_id_t, profiler: *mut mi_profiler_t) -> bool;
403 pub fn mi_profile(profiler: *mut mi_profiler_t) -> bool;
404 pub fn mi_profiler_start(profiler: *mut mi_profiler_t) -> bool;
405 pub fn mi_profiler_stop(profiler: *mut mi_profiler_t) -> bool;
406}
407
408unsafe extern "C" {
411 pub fn mi_posix_memalign(p: *mut *mut c_void, alignment: size_t, size: size_t) -> c_int;
412 pub fn mi_memalign(alignment: size_t, size: size_t) -> *mut c_void;
413 pub fn mi_malloc_size(p: *const c_void) -> size_t;
414 pub fn mi_malloc_usable_size(p: *const c_void) -> size_t;
415}
416
417unsafe extern "C" {
420 pub fn mi_stats_get_json(buf_size: size_t, buf: *mut c_char) -> *mut c_char;
421 pub fn mi_stats_print_out(out: Option<mi_output_fun>, arg: *mut c_void);
422 pub fn mi_stats_reset();
423 pub fn mi_heap_stats_get_json(
424 heap: *mut mi_heap_t,
425 buf_size: size_t,
426 buf: *mut c_char,
427 ) -> *mut c_char;
428 pub fn mi_heap_stats_print_out(
429 heap: *mut mi_heap_t,
430 out: Option<mi_output_fun>,
431 arg: *mut c_void,
432 );
433 pub fn mi_theap_stats_merge_to_heap(theap: *mut mi_theap_t);
434}