#![doc(html_root_url="https://docs.rs/jemalloc-ctl/0.1")]
#![warn(missing_docs)]
use std::os::raw::{c_int, c_void, c_char};
use std::io;
use std::mem;
use std::ptr;
pub mod stats;
pub mod thread;
extern "C" {
#[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
target_os = "dragonfly", target_os = "windows", target_env = "musl"),
link_name = "je_mallctlnametomib")]
fn mallctlnametomib(name: *const c_char, mibp: *mut usize, miblenp: *mut usize) -> c_int;
#[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
target_os = "dragonfly", target_os = "windows", target_env = "musl"),
link_name = "je_mallctlbymib")]
fn mallctlbymib(
mib: *const usize,
miblen: usize,
oldp: *mut c_void,
oldlenp: *mut usize,
newp: *mut c_void,
newlen: usize,
) -> c_int;
}
unsafe fn name_to_mib(name: &str, mib: &mut [usize]) -> io::Result<()> {
let mut len = mib.len();
cvt(mallctlnametomib(
name.as_ptr() as *const _,
mib.as_mut_ptr(),
&mut len,
))?;
debug_assert_eq!(mib.len(), len);
Ok(())
}
unsafe fn get<T>(mib: &[usize]) -> io::Result<T> {
let mut value = mem::uninitialized::<T>();
let mut len = mem::size_of::<T>();
cvt(mallctlbymib(
mib.as_ptr(),
mib.len(),
&mut value as *mut _ as *mut _,
&mut len,
ptr::null_mut(),
0,
))?;
debug_assert_eq!(len, mem::size_of::<T>());
Ok(value)
}
unsafe fn get_set<T>(mib: &[usize], mut value: T) -> io::Result<T> {
let mut len = mem::size_of::<T>();
cvt(mallctlbymib(
mib.as_ptr(),
mib.len(),
&mut value as *mut _ as *mut _,
&mut len,
&mut value as *mut _ as *mut _,
len,
))?;
debug_assert_eq!(len, mem::size_of::<T>());
Ok(value)
}
fn cvt(ret: c_int) -> io::Result<()> {
if ret == 0 {
Ok(())
} else {
Err(io::Error::from_raw_os_error(ret as i32))
}
}
#[derive(Copy, Clone)]
pub struct Epoch([usize; 1]);
impl Epoch {
pub fn new() -> io::Result<Epoch> {
let mut mib = [0; 1];
unsafe {
name_to_mib("epoch\0", &mut mib)?;
}
Ok(Epoch(mib))
}
pub fn advance(&self) -> io::Result<u64> {
unsafe { get_set(&self.0, 1) }
}
}