#![allow(nonstandard_style)]
use core::ffi::c_void;
use cty::{c_char, c_int, c_long, c_ulonglong};
pub const MI_SMALL_SIZE_MAX: usize = 128 * core::mem::size_of::<*mut c_void>();
extern "C" {
pub fn mi_calloc(count: usize, size: usize) -> *mut c_void;
pub fn mi_mallocn(count: usize, size: usize) -> *mut c_void;
pub fn mi_reallocn(p: *mut c_void, count: usize, size: usize) -> *mut c_void;
pub fn mi_expand(p: *mut c_void, newsize: usize) -> *mut c_void;
pub fn mi_reallocf(p: *mut c_void, newsize: usize) -> *mut c_void;
pub fn mi_strdup(s: *const c_char) -> *mut c_char;
pub fn mi_strndup(s: *const c_char, n: usize) -> *mut c_char;
pub fn mi_realpath(fname: *const c_char, resolved_name: *mut c_char) -> *mut c_char;
pub fn mi_calloc_aligned(count: usize, size: usize, alignment: usize) -> *mut c_void;
pub fn mi_malloc_aligned_at(size: usize, alignment: usize, offset: usize) -> *mut c_void;
pub fn mi_zalloc_aligned_at(size: usize, alignment: usize, offset: usize) -> *mut c_void;
pub fn mi_posix_memalign(ptr: *mut *mut c_void, alignment: usize, size: usize) -> c_int;
pub fn mi_aligned_alloc(alignment: usize, size: usize) -> *mut c_void;
pub fn mi_calloc_aligned_at(
count: usize,
size: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_realloc_aligned_at(
p: *mut c_void,
newsize: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_rezalloc(p: *mut c_void, newsize: usize) -> *mut c_void;
pub fn mi_recalloc(p: *mut c_void, newcount: usize, size: usize) -> *mut c_void;
pub fn mi_rezalloc_aligned(p: *mut c_void, newsize: usize, alignment: usize) -> *mut c_void;
pub fn mi_rezalloc_aligned_at(
p: *mut c_void,
newsize: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_recalloc_aligned(
p: *mut c_void,
newcount: usize,
size: usize,
alignment: usize,
) -> *mut c_void;
pub fn mi_recalloc_aligned_at(
p: *mut c_void,
newcount: usize,
size: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_malloc_small(size: usize) -> *mut c_void;
pub fn mi_zalloc_small(size: usize) -> *mut c_void;
pub fn mi_usable_size(p: *const c_void) -> usize;
pub fn mi_good_size(size: usize) -> usize;
pub fn mi_collect(force: bool);
pub fn mi_cfree(p: *mut c_void);
pub fn mi_is_in_heap_region(p: *const c_void) -> bool;
pub fn mi_free_size_aligned(p: *mut c_void, size: usize, alignment: usize);
pub fn mi_free_size(p: *mut c_void, size: usize);
pub fn mi_free_aligned(p: *mut c_void, alignment: usize);
pub fn mi_stats_print(_: *mut c_void);
pub fn mi_stats_print_out(out: mi_output_fun, arg: *mut c_void);
pub fn mi_stats_reset();
pub fn mi_stats_merge();
pub fn mi_version() -> c_int;
pub fn mi_thread_init();
pub fn mi_process_init();
pub fn mi_process_info(
elapsed_msecs: *mut usize,
user_msecs: *mut usize,
system_msecs: *mut usize,
current_rss: *mut usize,
peak_rss: *mut usize,
current_commit: *mut usize,
peak_commit: *mut usize,
page_faults: *mut usize,
);
pub fn mi_thread_done();
pub fn mi_thread_stats_print_out(out: mi_output_fun, arg: *mut c_void);
pub fn mi_register_output(out: mi_output_fun, arg: *mut c_void);
pub fn mi_register_deferred_free(out: mi_deferred_free_fun, arg: *mut c_void);
pub fn mi_register_error(out: mi_error_fun, arg: *mut c_void);
}
pub type mi_output_fun = Option<unsafe extern "C" fn(msg: *const c_char, arg: *mut c_void)>;
pub type mi_deferred_free_fun =
Option<unsafe extern "C" fn(force: bool, heartbeat: c_ulonglong, arg: *mut c_void)>;
pub type mi_error_fun = Option<unsafe extern "C" fn(code: c_int, arg: *mut c_void)>;
pub type mi_option_t = c_int;
#[cfg(feature = "arena")]
pub type mi_arena_id_t = c_int;
pub const mi_option_show_errors: mi_option_t = 0;
pub const mi_option_show_stats: mi_option_t = 1;
pub const mi_option_verbose: mi_option_t = 2;
pub const mi_option_large_os_pages: mi_option_t = 6;
pub const mi_option_reserve_huge_os_pages: mi_option_t = 7;
pub const mi_option_reserve_huge_os_pages_at: mi_option_t = 8;
pub const mi_option_reserve_os_memory: mi_option_t = 9;
pub const mi_option_eager_commit_delay: mi_option_t = 14;
pub const mi_option_use_numa_nodes: mi_option_t = 16;
pub const mi_option_limit_os_alloc: mi_option_t = 17;
pub const mi_option_os_tag: mi_option_t = 18;
pub const mi_option_max_errors: mi_option_t = 19;
pub const mi_option_max_warnings: mi_option_t = 20;
pub const mi_option_max_segment_reclaim: mi_option_t = 21;
pub const mi_option_destroy_on_exit: mi_option_t = 22;
pub const mi_option_arena_reserve: mi_option_t = 23;
pub const mi_option_arena_purge_mult: mi_option_t = 24;
pub const mi_option_purge_extend_delay: mi_option_t = 25;
pub const mi_option_abandoned_reclaim_on_free: mi_option_t = 26;
pub const mi_option_disallow_arena_alloc: mi_option_t = 27;
pub const mi_option_retry_on_oom: mi_option_t = 28;
pub const mi_option_visit_abandoned: mi_option_t = 29;
pub const mi_option_guarded_min: mi_option_t = 30;
pub const mi_option_guarded_max: mi_option_t = 31;
pub const mi_option_guarded_precise: mi_option_t = 32;
pub const mi_option_guarded_sample_rate: mi_option_t = 33;
pub const mi_option_guarded_sample_seed: mi_option_t = 34;
pub const mi_option_target_segments_per_thread: mi_option_t = 35;
pub const mi_option_generic_collect: mi_option_t = 36;
pub const _mi_option_last: mi_option_t = 37;
extern "C" {
pub fn mi_option_is_enabled(option: mi_option_t) -> bool;
pub fn mi_option_set_enabled(option: mi_option_t, enable: bool);
pub fn mi_option_set_enabled_default(option: mi_option_t, enable: bool);
pub fn mi_option_get(option: mi_option_t) -> c_long;
pub fn mi_option_set(option: mi_option_t, value: c_long);
pub fn mi_option_set_default(option: mi_option_t, value: c_long);
}
pub enum mi_heap_t {}
#[repr(C)]
#[derive(Debug, Clone, Copy)]
pub struct mi_heap_area_t {
pub blocks: *mut c_void,
pub reserved: usize,
pub committed: usize,
pub used: usize,
pub block_size: usize,
pub full_block_size: usize,
pub heap_tag: c_int,
}
pub type mi_block_visit_fun = Option<
unsafe extern "C" fn(
heap: *const mi_heap_t,
area: *const mi_heap_area_t,
block: *mut c_void,
block_size: usize,
arg: *mut c_void,
) -> bool,
>;
extern "C" {
pub fn mi_heap_new() -> *mut mi_heap_t;
pub fn mi_heap_delete(heap: *mut mi_heap_t);
pub fn mi_heap_destroy(heap: *mut mi_heap_t);
pub fn mi_heap_set_default(heap: *mut mi_heap_t) -> *mut mi_heap_t;
pub fn mi_heap_get_default() -> *mut mi_heap_t;
pub fn mi_heap_get_backing() -> *mut mi_heap_t;
pub fn mi_heap_collect(heap: *mut mi_heap_t, force: bool);
pub fn mi_heap_malloc(heap: *mut mi_heap_t, size: usize) -> *mut c_void;
pub fn mi_heap_zalloc(heap: *mut mi_heap_t, size: usize) -> *mut c_void;
pub fn mi_heap_calloc(heap: *mut mi_heap_t, count: usize, size: usize) -> *mut c_void;
pub fn mi_heap_mallocn(heap: *mut mi_heap_t, count: usize, size: usize) -> *mut c_void;
pub fn mi_heap_malloc_small(heap: *mut mi_heap_t, size: usize) -> *mut c_void;
pub fn mi_heap_realloc(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void;
pub fn mi_heap_reallocn(
heap: *mut mi_heap_t,
p: *mut c_void,
count: usize,
size: usize,
) -> *mut c_void;
pub fn mi_heap_reallocf(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void;
pub fn mi_heap_strdup(heap: *mut mi_heap_t, s: *const c_char) -> *mut c_char;
pub fn mi_heap_strndup(heap: *mut mi_heap_t, s: *const c_char, n: usize) -> *mut c_char;
pub fn mi_heap_realpath(
heap: *mut mi_heap_t,
fname: *const c_char,
resolved_name: *mut c_char,
) -> *mut c_char;
pub fn mi_heap_malloc_aligned(
heap: *mut mi_heap_t,
size: usize,
alignment: usize,
) -> *mut c_void;
pub fn mi_heap_malloc_aligned_at(
heap: *mut mi_heap_t,
size: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_heap_zalloc_aligned(
heap: *mut mi_heap_t,
size: usize,
alignment: usize,
) -> *mut c_void;
pub fn mi_heap_zalloc_aligned_at(
heap: *mut mi_heap_t,
size: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_heap_calloc_aligned(
heap: *mut mi_heap_t,
count: usize,
size: usize,
alignment: usize,
) -> *mut c_void;
pub fn mi_heap_calloc_aligned_at(
heap: *mut mi_heap_t,
count: usize,
size: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_heap_realloc_aligned(
heap: *mut mi_heap_t,
p: *mut c_void,
newsize: usize,
alignment: usize,
) -> *mut c_void;
pub fn mi_heap_realloc_aligned_at(
heap: *mut mi_heap_t,
p: *mut c_void,
newsize: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_heap_rezalloc(heap: *mut mi_heap_t, p: *mut c_void, newsize: usize) -> *mut c_void;
pub fn mi_heap_recalloc(
heap: *mut mi_heap_t,
p: *mut c_void,
newcount: usize,
size: usize,
) -> *mut c_void;
pub fn mi_heap_rezalloc_aligned(
heap: *mut mi_heap_t,
p: *mut c_void,
newsize: usize,
alignment: usize,
) -> *mut c_void;
pub fn mi_heap_rezalloc_aligned_at(
heap: *mut mi_heap_t,
p: *mut c_void,
newsize: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_heap_recalloc_aligned(
heap: *mut mi_heap_t,
p: *mut c_void,
newcount: usize,
size: usize,
alignment: usize,
) -> *mut c_void;
pub fn mi_heap_recalloc_aligned_at(
heap: *mut mi_heap_t,
p: *mut c_void,
newcount: usize,
size: usize,
alignment: usize,
offset: usize,
) -> *mut c_void;
pub fn mi_heap_contains_block(heap: *mut mi_heap_t, p: *const c_void) -> bool;
pub fn mi_heap_check_owned(heap: *mut mi_heap_t, p: *const c_void) -> bool;
pub fn mi_check_owned(p: *const c_void) -> bool;
pub fn mi_heap_visit_blocks(
heap: *const mi_heap_t,
visit_all_blocks: bool,
visitor: mi_block_visit_fun,
arg: *mut c_void,
) -> bool;
#[cfg(feature = "arena")]
pub fn mi_heap_new_in_arena(arena_id: mi_arena_id_t) -> *mut mi_heap_t;
#[cfg(feature = "arena")]
pub fn mi_reserve_os_memory_ex(
size: usize,
commit: bool,
allow_large: bool,
exclusive: bool,
arena_id: *mut mi_arena_id_t,
) -> c_int;
#[cfg(feature = "arena")]
pub fn mi_manage_os_memory_ex(
start: *const c_void,
size: usize,
is_committed: bool,
is_large: bool,
is_zero: bool,
numa_node: c_int,
exclusive: bool,
arena_id: *mut mi_arena_id_t,
) -> bool;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::mi_malloc;
#[test]
fn it_calculates_usable_size() {
let ptr = unsafe { mi_malloc(32) } as *mut u8;
let usable_size = unsafe { mi_usable_size(ptr as *mut c_void) };
assert!(
usable_size >= 32,
"usable_size should at least equal to the allocated size"
);
}
#[test]
fn runtime_stable_option() {
unsafe {
assert_eq!(mi_option_get(mi_option_show_errors), 0);
mi_option_set(mi_option_show_errors, 1);
assert_eq!(mi_option_get(mi_option_show_errors), 1);
assert_eq!(mi_option_get(mi_option_show_stats), 0);
mi_option_set(mi_option_show_stats, 1);
assert_eq!(mi_option_get(mi_option_show_stats), 1);
assert_eq!(mi_option_get(mi_option_verbose), 0);
mi_option_set(mi_option_verbose, 1);
assert_eq!(mi_option_get(mi_option_verbose), 1);
}
}
}