1use crate::MiMalloc;
4use core::ffi::c_void;
5
6#[derive(Debug, Clone, Copy, Default)]
8pub struct ProcessInfo {
9 pub elapsed_msecs: usize,
10 pub user_msecs: usize,
11 pub system_msecs: usize,
12 pub current_rss: usize,
13 pub peak_rss: usize,
14 pub current_commit: usize,
15 pub peak_commit: usize,
16 pub page_faults: usize,
17}
18
19impl MiMalloc {
20 #[inline]
22 pub fn version() -> i32 {
23 unsafe { rustfs_mimalloc_sys::mi_version() }
24 }
25
26 #[inline]
28 pub fn collect(force: bool) {
29 unsafe { rustfs_mimalloc_sys::mi_collect(force) }
30 }
31
32 #[inline]
37 pub unsafe fn usable_size(ptr: *const u8) -> usize {
38 unsafe { rustfs_mimalloc_sys::mi_usable_size(ptr as *const c_void) }
39 }
40
41 pub fn process_info() -> ProcessInfo {
43 let mut info = ProcessInfo::default();
44 unsafe {
45 rustfs_mimalloc_sys::mi_process_info(
46 &mut info.elapsed_msecs,
47 &mut info.user_msecs,
48 &mut info.system_msecs,
49 &mut info.current_rss,
50 &mut info.peak_rss,
51 &mut info.current_commit,
52 &mut info.peak_commit,
53 &mut info.page_faults,
54 );
55 }
56 info
57 }
58
59 pub fn stats_json() -> String {
63 unsafe {
64 crate::ffi::owned_mimalloc_string(rustfs_mimalloc_sys::mi_stats_get_json(
65 0,
66 core::ptr::null_mut(),
67 ))
68 }
69 }
70
71 pub fn stats_print() -> String {
73 crate::ffi::collect_mimalloc_output(|out, arg| unsafe {
74 rustfs_mimalloc_sys::mi_stats_print_out(out, arg);
75 })
76 }
77
78 #[inline]
80 pub fn stats_reset() {
81 unsafe { rustfs_mimalloc_sys::mi_stats_reset() }
82 }
83
84 pub fn process_info_print() -> String {
86 crate::ffi::collect_mimalloc_output(|out, arg| unsafe {
87 rustfs_mimalloc_sys::mi_process_info_print_out(out, arg);
88 })
89 }
90
91 #[inline]
95 pub fn option_is_enabled(option: rustfs_mimalloc_sys::mi_option_t) -> bool {
96 unsafe { rustfs_mimalloc_sys::mi_option_is_enabled(option) }
97 }
98
99 #[inline]
101 pub fn option_get(option: rustfs_mimalloc_sys::mi_option_t) -> rustfs_mimalloc_sys::c_long {
102 unsafe { rustfs_mimalloc_sys::mi_option_get(option) }
103 }
104
105 #[inline]
107 pub fn option_get_size(option: rustfs_mimalloc_sys::mi_option_t) -> usize {
108 unsafe { rustfs_mimalloc_sys::mi_option_get_size(option) }
109 }
110
111 #[inline]
121 pub fn option_set(
122 option: rustfs_mimalloc_sys::mi_option_t,
123 value: rustfs_mimalloc_sys::c_long,
124 ) {
125 unsafe { rustfs_mimalloc_sys::mi_option_set(option, value) }
126 }
127
128 #[inline]
130 pub fn option_enable(option: rustfs_mimalloc_sys::mi_option_t) {
131 unsafe { rustfs_mimalloc_sys::mi_option_enable(option) }
132 }
133
134 #[inline]
136 pub fn option_disable(option: rustfs_mimalloc_sys::mi_option_t) {
137 unsafe { rustfs_mimalloc_sys::mi_option_disable(option) }
138 }
139}
140
141#[cfg(test)]
144mod tests {
145 use super::*;
146 use rustfs_mimalloc_sys::mi_option_t;
147
148 #[test]
149 fn version_is_v3() {
150 assert!(MiMalloc::version() >= 30500, "expected >= V3.5.0");
151 }
152
153 #[test]
154 fn stats_json_not_empty() {
155 let json = MiMalloc::stats_json();
156 assert!(!json.is_empty());
157 }
158
159 #[test]
160 fn stats_print_not_empty() {
161 let stats = MiMalloc::stats_print();
162 assert!(!stats.is_empty());
163 }
164
165 #[test]
166 fn stats_reset_smoke() {
167 MiMalloc::stats_reset();
168 }
169
170 #[test]
171 fn process_info_print_not_empty() {
172 let info = MiMalloc::process_info_print();
173 assert!(!info.is_empty());
174 }
175
176 #[test]
177 fn option_roundtrip() {
178 let _ = MiMalloc::option_get(mi_option_t::mi_option_purge_delay);
180 let _ = MiMalloc::option_is_enabled(mi_option_t::mi_option_show_errors);
181 }
182
183 #[test]
184 fn process_info_smoke() {
185 let info = MiMalloc::process_info();
186 let _ = info;
187 }
188
189 #[test]
190 fn usable_size_at_least_requested() {
191 unsafe {
192 let ptr = rustfs_mimalloc_sys::mi_malloc(64);
193 assert!(MiMalloc::usable_size(ptr as *const u8) >= 64);
194 rustfs_mimalloc_sys::mi_free(ptr);
195 }
196 }
197}