Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion libmimalloc-sys/src/extended.rs
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,12 @@ extern "C" {
///
/// Note: This function is thread safe.
pub fn mi_register_error(out: mi_error_fun, arg: *mut c_void);

/// Get the statistics for the current subprocess aggregated over all its heaps as JSON.
///
/// Returns pointer to the buffer or NULL on failure. Use mi_free() to free the buffer if the buf parameter was NULL.
#[cfg(not(feature = "v2"))]
pub fn mi_stats_get_json(buf_size: usize, buf: *mut c_char) -> *mut c_char;
}

/// An output callback. Must be thread-safe.
Expand Down Expand Up @@ -1092,7 +1098,7 @@ mod tests {

#[test]
fn it_calculates_usable_size() {
let ptr = unsafe { mi_malloc(32) } as *mut u8;
let ptr = unsafe { crate::mi_malloc(32) } as *mut u8;
let usable_size = unsafe { mi_usable_size(ptr as *mut c_void) };
assert!(
usable_size >= 32,
Expand Down
33 changes: 33 additions & 0 deletions src/extended.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use crate::MiMalloc;
use core::ffi::c_void;
#[cfg(not(feature = "v2"))]
use core::ffi::{c_char, CStr};

impl MiMalloc {
/// Get the mimalloc version.
Expand All @@ -17,6 +19,29 @@ impl MiMalloc {
pub unsafe fn usable_size(&self, ptr: *const u8) -> usize {
ffi::mi_usable_size(ptr as *const c_void)
}

/// Call the given function with a string version of the JSON stats for the whole process
///
/// Allocates (using mimalloc itself) to store the JSON structure.
#[cfg(not(feature = "v2"))]
pub fn with_stats_json<F, O>(f: F) -> Result<O, &'static str>
where
F: FnOnce(&str) -> O,
{
unsafe {
let buf = ffi::mi_stats_get_json(0, core::ptr::null::<c_char>() as *mut _);
if buf.is_null() {
return Err("failed to call mi_stats_get_json");
}
let cstr = CStr::from_ptr(buf);
let slice = cstr
.to_str()
.map_err(|_| "mi_stats_get_json contained invalid UTF-8")?;
let o = f(slice);
ffi::mi_free(buf as _);
Ok(o)
}
}
}

#[cfg(test)]
Expand All @@ -43,4 +68,12 @@ mod test {
assert!(usable_size >= 8);
}
}

#[test]
#[cfg(not(feature = "v2"))]
fn test_with_stats_json() {
let (first_char, len) = MiMalloc::with_stats_json(|f| (f.chars().next(), f.len())).unwrap();
assert_eq!(first_char, Some('{'));
assert!(len > 1);
}
}