auto merge of #4917 : nnethercote/servo/fix-jemalloc-reporting, r=jdm

It turns out you need to send an "epoch" request to jemalloc before
asking for a measurement otherwise you get stale data! Heavens.
This commit is contained in:
bors-servo 2015-02-13 06:54:56 -07:00
commit 7acc6887d5

View file

@ -198,17 +198,31 @@ extern {
newp: *mut c_void, newlen: size_t) -> c_int; newp: *mut c_void, newlen: size_t) -> c_int;
} }
fn get_jemalloc_stat(name: &'static str) -> Option<u64> { fn get_jemalloc_stat(value_name: &str) -> Option<u64> {
let mut old: size_t = 0; // Before we request the measurement of interest, we first send an "epoch"
let c_name = CString::from_slice(name.as_bytes()); // request. Without that jemalloc gives cached statistics(!) which can be
let oldp = &mut old as *mut _ as *mut c_void; // highly inaccurate.
let mut oldlen = size_of::<size_t>() as size_t; let epoch_name = "epoch";
let rv: c_int; let epoch_c_name = CString::from_slice(epoch_name.as_bytes());
let mut epoch: u64 = 0;
let epoch_ptr = &mut epoch as *mut _ as *mut c_void;
let mut epoch_len = size_of::<u64>() as size_t;
let value_c_name = CString::from_slice(value_name.as_bytes());
let mut value: size_t = 0;
let value_ptr = &mut value as *mut _ as *mut c_void;
let mut value_len = size_of::<size_t>() as size_t;
let mut rv: c_int;
unsafe { unsafe {
rv = je_mallctl(c_name.as_ptr(), oldp, &mut oldlen, null_mut(), 0); // Using the same values for the `old` and `new` parameters is enough
mem::forget(c_name); // XXX correct? // to get the statistics updated.
rv = je_mallctl(epoch_c_name.as_ptr(), epoch_ptr, &mut epoch_len, epoch_ptr, epoch_len);
if rv == 0 {
rv = je_mallctl(value_c_name.as_ptr(), value_ptr, &mut value_len, null_mut(), 0);
}
} }
if rv == 0 { Some(old as u64) } else { None } if rv == 0 { Some(value as u64) } else { None }
} }
// Like std::macros::try!, but for Option<>. // Like std::macros::try!, but for Option<>.