Skip to main content

mimalloc_pprof/
sys.rs

1//! Raw bindings to the in-tree mimalloc static amalgamation.
2
3use core::ffi::c_char;
4use core::ffi::c_int;
5use core::ffi::c_void;
6
7pub type MiProfWriteFun = unsafe extern "C" fn(*mut c_void, *const c_char, usize);
8
9/// Mirrors `MI_PROF_STAT_VERSION` in `include/mimalloc/profile.h`.
10pub const MI_PROF_STAT_VERSION: c_int = 2;
11
12/// Mirrors `mi_prof_stats_t` (include/mimalloc/profile.h) field-for-field.
13#[repr(C)]
14#[allow(non_camel_case_types)]
15pub struct mi_prof_stats_t {
16    pub size: usize,
17    pub version: c_int,
18    pub enabled: bool,
19    pub accum: bool,
20    pub sample_rate: usize,
21    pub live_samples: usize,
22    pub live_bytes: usize,
23    pub accum_samples: usize,
24    pub accum_bytes: usize,
25    pub unique_stacks: usize,
26    pub arena_committed: usize,
27    pub stack_table_overflows: usize,
28    /// v2. Mirrors `mi_prof_stats_t.dropped_samples`: count of ALL dropped
29    /// samples (record-alloc failure, stack-intern failure, including the
30    /// `MI_PROF_STACK_CAP` cap); `stack_table_overflows` is a subset, so
31    /// `dropped_samples >= stack_table_overflows` always.
32    pub dropped_samples: usize,
33}
34
35/// Mirrors `MI_PROF_CONFIG_VERSION` in `include/mimalloc/profile.h`.
36pub const MI_PROF_CONFIG_VERSION: c_int = 1;
37
38/// Mirrors `MI_PROF_FORMAT_TEXT` / `MI_PROF_FORMAT_PROTO` (include/mimalloc/profile.h).
39pub const MI_PROF_FORMAT_TEXT: c_int = 0;
40pub const MI_PROF_FORMAT_PROTO: c_int = 1;
41
42/// Mirrors `mi_prof_config_mode_t`'s `MI_PROF_CONFIG_FALLBACK` /
43/// `MI_PROF_CONFIG_OVERRIDE` (include/mimalloc/profile.h).
44pub const MI_PROF_CONFIG_FALLBACK: c_int = 0;
45pub const MI_PROF_CONFIG_OVERRIDE: c_int = 1;
46
47/// Mirrors `mi_prof_config_t` (include/mimalloc/profile.h) field-for-field.
48#[repr(C)]
49#[allow(non_camel_case_types)]
50pub struct mi_prof_config_t {
51    pub size: usize,
52    pub version: c_int,
53    pub mode: c_int, // mi_prof_config_mode_t
54    pub sample_interval: usize,
55    pub max_profiler_bytes: usize,
56    pub seed: u64,
57    pub accum: bool,
58    pub max_stack_depth: usize,
59    pub dump_at_exit: *const c_char,
60    pub dump_format: c_int,
61}
62
63/// Mirrors `mi_prof_sample_info_t` (include/mimalloc/profile.h) field-for-field.
64#[repr(C)]
65#[allow(non_camel_case_types)]
66pub struct mi_prof_sample_info_t {
67    pub stack: *const *const c_void,
68    pub depth: usize,
69    pub live_objects: usize,
70    pub live_bytes: usize,
71    pub accum_objects: usize,
72    pub accum_bytes: usize,
73}
74
75#[allow(non_camel_case_types)]
76pub type mi_prof_visit_fun =
77    unsafe extern "C" fn(info: *const mi_prof_sample_info_t, arg: *mut c_void) -> bool;
78
79/// Opaque handle for `mi_prof_snapshot_t`; the profiler never hands out a
80/// value, only a pointer, so this type is never constructed on the Rust side.
81#[allow(non_camel_case_types)]
82pub enum mi_prof_snapshot_t {}
83
84/// Mirrors `mi_prof_module_info_t` (include/mimalloc/profile.h) field-for-field.
85#[repr(C)]
86#[allow(non_camel_case_types)]
87pub struct mi_prof_module_info_t {
88    pub path: *const c_char,
89    pub base: usize,
90    pub size: usize,
91}
92
93#[allow(non_camel_case_types)]
94pub type mi_prof_module_visit_fun =
95    unsafe extern "C" fn(info: *const mi_prof_module_info_t, arg: *mut c_void) -> bool;
96
97unsafe extern "C" {
98    pub fn mi_malloc(size: usize) -> *mut c_void;
99    pub fn mi_zalloc(size: usize) -> *mut c_void;
100    pub fn mi_calloc(count: usize, size: usize) -> *mut c_void;
101    pub fn mi_realloc(p: *mut c_void, newsize: usize) -> *mut c_void;
102    pub fn mi_free(p: *mut c_void);
103    pub fn mi_malloc_aligned(size: usize, alignment: usize) -> *mut c_void;
104    pub fn mi_zalloc_aligned(size: usize, alignment: usize) -> *mut c_void;
105    pub fn mi_realloc_aligned(p: *mut c_void, newsize: usize, alignment: usize) -> *mut c_void;
106    pub fn mi_usable_size(p: *const c_void) -> usize;
107    pub fn mi_prof_start(sample_rate: usize) -> bool;
108    pub fn mi_prof_start_seeded(sample_rate: usize, seed: u64) -> bool;
109    pub fn mi_prof_start_ex(config: *const mi_prof_config_t) -> bool;
110    pub fn mi_prof_stop();
111    pub fn mi_prof_is_enabled() -> bool;
112    pub fn mi_prof_dump(path: *const c_char) -> bool;
113    pub fn mi_prof_dump_writer(write: Option<MiProfWriteFun>, arg: *mut c_void) -> bool;
114    /// profile.proto (google/pprof) writer: same sample/period/mapping semantics as
115    /// `mi_prof_dump`/`mi_prof_dump_writer` but encoded as an uncompressed, binary
116    /// pprof Profile message instead of the legacy "heap profile:" text.
117    pub fn mi_prof_dump_proto(path: *const c_char) -> bool;
118    pub fn mi_prof_dump_proto_writer(write: Option<MiProfWriteFun>, arg: *mut c_void) -> bool;
119    pub fn mi_prof_reset();
120    pub fn mi_prof_debug_stats(records: *mut usize, bytes: *mut usize, unique_stacks: *mut usize);
121    pub fn mi_prof_stats_get(stats: *mut mi_prof_stats_t) -> bool;
122    pub fn mi_prof_visit(visitor: mi_prof_visit_fun, arg: *mut c_void) -> bool;
123    pub fn mi_prof_snapshot_new() -> *mut mi_prof_snapshot_t;
124    pub fn mi_prof_snapshot_visit(
125        snap: *const mi_prof_snapshot_t,
126        visitor: mi_prof_visit_fun,
127        arg: *mut c_void,
128    ) -> bool;
129    pub fn mi_prof_snapshot_free(snap: *mut mi_prof_snapshot_t);
130    /// Structured module (mapping) enumeration, e.g. to build pprof Mapping entries
131    /// yourself. No profiler lock is taken: module lists are OS-owned, not part of
132    /// the sampled-allocation table. `info` (and `info->path`) are valid only for
133    /// the duration of the callback.
134    pub fn mi_prof_modules_visit(visitor: mi_prof_module_visit_fun, arg: *mut c_void) -> bool;
135
136    /// Mirrors `mi_unwrapped_malloc` (include/mimalloc/memory-events.h): backed
137    /// directly by the raw OS layer, never by the hooked `mi_malloc` family.
138    /// See that header's "Stable public unwrapped instrumentation allocation
139    /// path" comment for the full contract.
140    pub fn mi_unwrapped_malloc(size: usize, alignment: usize) -> *mut c_void;
141    /// Mirrors `mi_unwrapped_free` (include/mimalloc/memory-events.h).
142    pub fn mi_unwrapped_free(p: *mut c_void);
143    /// Mirrors `mi_unwrapped_realloc` (include/mimalloc/memory-events.h).
144    pub fn mi_unwrapped_realloc(p: *mut c_void, new_size: usize, alignment: usize) -> *mut c_void;
145}