cache page_size
page_size is used in every nearly every pointer calculation in os.rs, and the Stack methods are called fairly often. It's definitely not worth spilling registers for to call out to a libc function. With this change, page_size becomes effectively free. It is cached in an atomic usize, with relaxed ordering, so no actual atomic operations are involved. Benchmark: ``` test bench_page_size ... bench: 5 ns/iter (+/- 1) test bench_page_size_cached ... bench: 0 ns/iter (+/- 0) ```
This commit is contained in:
parent
52c0c92cd8
commit
cbc10fd311
|
@ -1,5 +1,20 @@
|
||||||
pub use self::imp::*;
|
use core::atomic::{ATOMIC_USIZE_INIT, AtomicUsize, Ordering};
|
||||||
|
|
||||||
|
pub use self::imp::{map_stack, protect_stack, unmap_stack};
|
||||||
|
use self::imp::sys_page_size;
|
||||||
|
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
#[path = "unix.rs"]
|
#[path = "unix.rs"]
|
||||||
mod imp;
|
mod imp;
|
||||||
|
|
||||||
|
static PAGE_SIZE_CACHE: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||||
|
pub fn page_size() -> usize {
|
||||||
|
match PAGE_SIZE_CACHE.load(Ordering::Relaxed) {
|
||||||
|
0 => {
|
||||||
|
let page_size = sys_page_size();
|
||||||
|
PAGE_SIZE_CACHE.store(page_size, Ordering::Relaxed);
|
||||||
|
page_size
|
||||||
|
}
|
||||||
|
page_size => page_size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -3,10 +3,13 @@ use core::prelude::*;
|
||||||
use self::libc::{c_void, c_int, size_t};
|
use self::libc::{c_void, c_int, size_t};
|
||||||
use self::libc::{mmap, mprotect, munmap};
|
use self::libc::{mmap, mprotect, munmap};
|
||||||
use self::libc::MAP_FAILED;
|
use self::libc::MAP_FAILED;
|
||||||
|
use super::page_size;
|
||||||
|
|
||||||
use core::ptr;
|
use core::ptr;
|
||||||
|
|
||||||
pub fn page_size() -> usize {
|
#[cold]
|
||||||
|
#[inline(never)]
|
||||||
|
pub fn sys_page_size() -> usize {
|
||||||
unsafe {
|
unsafe {
|
||||||
libc::sysconf(libc::_SC_PAGESIZE) as usize
|
libc::sysconf(libc::_SC_PAGESIZE) as usize
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue