diff options
author | bors-servo <metajack+bors@gmail.com> | 2015-02-13 06:54:56 -0700 |
---|---|---|
committer | bors-servo <metajack+bors@gmail.com> | 2015-02-13 06:54:56 -0700 |
commit | 7acc6887d5190b31e171be4823c6205e5e55ceec (patch) | |
tree | 5e109d75cc81e1daf86f875e4725ff16765d6e49 /components/util/memory.rs | |
parent | c0e2a237ec14d1aaecc5240e7ebb8f324c946834 (diff) | |
parent | eaee46de7cd2fc3958b2f7eb9bdd95ae48a62d96 (diff) | |
download | servo-7acc6887d5190b31e171be4823c6205e5e55ceec.tar.gz servo-7acc6887d5190b31e171be4823c6205e5e55ceec.zip |
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.
Diffstat (limited to 'components/util/memory.rs')
-rw-r--r-- | components/util/memory.rs | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/components/util/memory.rs b/components/util/memory.rs index d52500b62a3..27ee408b363 100644 --- a/components/util/memory.rs +++ b/components/util/memory.rs @@ -198,17 +198,31 @@ extern { newp: *mut c_void, newlen: size_t) -> c_int; } -fn get_jemalloc_stat(name: &'static str) -> Option<u64> { - let mut old: size_t = 0; - let c_name = CString::from_slice(name.as_bytes()); - let oldp = &mut old as *mut _ as *mut c_void; - let mut oldlen = size_of::<size_t>() as size_t; - let rv: c_int; +fn get_jemalloc_stat(value_name: &str) -> Option<u64> { + // Before we request the measurement of interest, we first send an "epoch" + // request. Without that jemalloc gives cached statistics(!) which can be + // highly inaccurate. + let epoch_name = "epoch"; + 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 { - rv = je_mallctl(c_name.as_ptr(), oldp, &mut oldlen, null_mut(), 0); - mem::forget(c_name); // XXX correct? + // Using the same values for the `old` and `new` parameters is enough + // 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<>. |