Skip to content

Commit da7a09c

Browse files
committed
feat: expose mi_stats_get_json and a safe wrapper around it
1 parent e639b55 commit da7a09c

2 files changed

Lines changed: 40 additions & 1 deletion

File tree

libmimalloc-sys/src/extended.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,12 @@ extern "C" {
447447
///
448448
/// Note: This function is thread safe.
449449
pub fn mi_register_error(out: mi_error_fun, arg: *mut c_void);
450+
451+
/// Get the statistics for the current subprocess aggregated over all its heaps as JSON.
452+
///
453+
/// Returns pointer to the buffer or NULL on failure. Use mi_free() to free the buffer if the buf parameter was NULL.
454+
#[cfg(not(feature = "v2"))]
455+
pub fn mi_stats_get_json(buf_size: usize, buf: *mut c_char) -> *mut c_char;
450456
}
451457

452458
/// An output callback. Must be thread-safe.
@@ -1092,7 +1098,7 @@ mod tests {
10921098

10931099
#[test]
10941100
fn it_calculates_usable_size() {
1095-
let ptr = unsafe { mi_malloc(32) } as *mut u8;
1101+
let ptr = unsafe { crate::mi_malloc(32) } as *mut u8;
10961102
let usable_size = unsafe { mi_usable_size(ptr as *mut c_void) };
10971103
assert!(
10981104
usable_size >= 32,

src/extended.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use crate::MiMalloc;
22
use core::ffi::c_void;
3+
#[cfg(not(feature = "v2"))]
4+
use core::ffi::{c_char, CStr};
35

46
impl MiMalloc {
57
/// Get the mimalloc version.
@@ -17,6 +19,29 @@ impl MiMalloc {
1719
pub unsafe fn usable_size(&self, ptr: *const u8) -> usize {
1820
ffi::mi_usable_size(ptr as *const c_void)
1921
}
22+
23+
/// Call the given function with a string version of the JSON stats for the whole process
24+
///
25+
/// Allocates (using mimalloc itself) to store the JSON structure.
26+
#[cfg(not(feature = "v2"))]
27+
pub fn with_stats_json<F, O>(f: F) -> Result<O, &'static str>
28+
where
29+
F: FnOnce(&str) -> O,
30+
{
31+
unsafe {
32+
let buf = ffi::mi_stats_get_json(0, core::ptr::null::<c_char>() as *mut _);
33+
if buf.is_null() {
34+
return Err("failed to call mi_stats_get_json");
35+
}
36+
let cstr = CStr::from_ptr(buf);
37+
let slice = cstr
38+
.to_str()
39+
.map_err(|_| "mi_stats_get_json contained invalid UTF-8")?;
40+
let o = f(slice);
41+
ffi::mi_free(buf as _);
42+
Ok(o)
43+
}
44+
}
2045
}
2146

2247
#[cfg(test)]
@@ -43,4 +68,12 @@ mod test {
4368
assert!(usable_size >= 8);
4469
}
4570
}
71+
72+
#[test]
73+
#[cfg(not(feature = "v2"))]
74+
fn test_with_stats_json() {
75+
let (first_char, len) = MiMalloc::with_stats_json(|f| (f.chars().next(), f.len())).unwrap();
76+
assert_eq!(first_char, Some('{'));
77+
assert!(len > 1);
78+
}
4679
}

0 commit comments

Comments
 (0)