)))]
const MAP_STACK: libc::c_int = 0;
+#[cfg(any(target_os = "linux", target_os = "android"))]
+const MAP_POPULATE: libc::c_int = libc::MAP_POPULATE;
+
+#[cfg(not(any(target_os = "linux", target_os = "android")))]
+const MAP_POPULATE: libc::c_int = 0;
+
pub struct MmapInner {
ptr: *mut libc::c_void,
len: usize,
} else {
Ok(MmapInner {
ptr: ptr.offset(alignment as isize),
- len: len,
+ len,
})
}
}
}
- pub fn map(len: usize, file: &File, offset: u64) -> io::Result<MmapInner> {
+ pub fn map(len: usize, file: &File, offset: u64, populate: bool) -> io::Result<MmapInner> {
+ let populate = if populate { MAP_POPULATE } else { 0 };
MmapInner::new(
len,
libc::PROT_READ,
- libc::MAP_SHARED,
+ libc::MAP_SHARED | populate,
file.as_raw_fd(),
offset,
)
}
- pub fn map_exec(len: usize, file: &File, offset: u64) -> io::Result<MmapInner> {
+ pub fn map_exec(len: usize, file: &File, offset: u64, populate: bool) -> io::Result<MmapInner> {
+ let populate = if populate { MAP_POPULATE } else { 0 };
MmapInner::new(
len,
libc::PROT_READ | libc::PROT_EXEC,
- libc::MAP_SHARED,
+ libc::MAP_SHARED | populate,
file.as_raw_fd(),
offset,
)
}
- pub fn map_mut(len: usize, file: &File, offset: u64) -> io::Result<MmapInner> {
+ pub fn map_mut(len: usize, file: &File, offset: u64, populate: bool) -> io::Result<MmapInner> {
+ let populate = if populate { MAP_POPULATE } else { 0 };
MmapInner::new(
len,
libc::PROT_READ | libc::PROT_WRITE,
- libc::MAP_SHARED,
+ libc::MAP_SHARED | populate,
file.as_raw_fd(),
offset,
)
}
- pub fn map_copy(len: usize, file: &File, offset: u64) -> io::Result<MmapInner> {
+ pub fn map_copy(len: usize, file: &File, offset: u64, populate: bool) -> io::Result<MmapInner> {
+ let populate = if populate { MAP_POPULATE } else { 0 };
MmapInner::new(
len,
libc::PROT_READ | libc::PROT_WRITE,
- libc::MAP_PRIVATE,
+ libc::MAP_PRIVATE | populate,
file.as_raw_fd(),
offset,
)
}
- pub fn map_copy_read_only(len: usize, file: &File, offset: u64) -> io::Result<MmapInner> {
+ pub fn map_copy_read_only(
+ len: usize,
+ file: &File,
+ offset: u64,
+ populate: bool,
+ ) -> io::Result<MmapInner> {
+ let populate = if populate { MAP_POPULATE } else { 0 };
MmapInner::new(
len,
libc::PROT_READ,
- libc::MAP_PRIVATE,
+ libc::MAP_PRIVATE | populate,
file.as_raw_fd(),
offset,
)
}
pub fn flush_async(&self, offset: usize, len: usize) -> io::Result<()> {
- let alignment = offset % page_size();
- let aligned_offset = offset - alignment;
- let aligned_len = len + alignment;
- let result = unsafe {
- libc::msync(
- self.ptr.offset(aligned_offset as isize),
- aligned_len as libc::size_t,
- libc::MS_ASYNC,
- )
- };
+ let alignment = (self.ptr as usize + offset) % page_size();
+ let offset = offset as isize - alignment as isize;
+ let len = len + alignment;
+ let result =
+ unsafe { libc::msync(self.ptr.offset(offset), len as libc::size_t, libc::MS_ASYNC) };
if result == 0 {
Ok(())
} else {