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)]
|
||||
#[path = "unix.rs"]
|
||||
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::{mmap, mprotect, munmap};
|
||||
use self::libc::MAP_FAILED;
|
||||
use super::page_size;
|
||||
|
||||
use core::ptr;
|
||||
|
||||
pub fn page_size() -> usize {
|
||||
#[cold]
|
||||
#[inline(never)]
|
||||
pub fn sys_page_size() -> usize {
|
||||
unsafe {
|
||||
libc::sysconf(libc::_SC_PAGESIZE) as usize
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user