pub fn advise_huge_pages<T>(memory: &mut [T]) {
#[cfg(target_os = "linux")]
{
const HUGE_PAGE_SIZE: usize = 2 << 20;
const PAGE_SIZE: usize = 4 << 10;
let start = memory.as_mut_ptr() as usize;
let end = start + std::mem::size_of_val(memory);
let aligned_start = start.next_multiple_of(PAGE_SIZE);
let aligned_end = end & !(PAGE_SIZE - 1);
if aligned_end < aligned_start + HUGE_PAGE_SIZE {
return;
}
let region = aligned_start as *mut libc::c_void;
let region_len = aligned_end - aligned_start;
let _ = unsafe { libc::madvise(region, region_len, libc::MADV_HUGEPAGE) };
}
#[cfg(not(target_os = "linux"))]
{
let _ = memory;
}
}
pub fn vec_with_capacity<T>(capacity: usize) -> Vec<T> {
let mut vec = Vec::with_capacity(capacity);
advise_huge_pages(vec.spare_capacity_mut());
vec
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use super::*;
use crate::tests::test;
#[macro_rules_attr::apply(test)]
fn advising_huge_pages_is_harmless() {
for len in [0, 1, 4 << 10, (2 << 20) + 17, 8 << 20] {
let mut memory = vec_with_capacity::<u8>(len);
advise_huge_pages(memory.spare_capacity_mut());
memory.resize(len, 42);
assert!(memory.iter().all(|&x| x == 42));
}
}
}