From 791f25243788bb360e52ccf780f972bb60335329 Mon Sep 17 00:00:00 2001 From: qiujiangkun Date: Mon, 14 Sep 2020 23:25:58 +0800 Subject: [PATCH 1/3] add resize() --- src/lib.rs | 36 ++++++++++++++++++++++++++++++++++++ src/unix.rs | 44 ++++++++++++++++++++++++++++++++++---------- 2 files changed, 70 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 24b6d422..9d7ed8e7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -638,6 +638,31 @@ impl MmapMut { self.inner.make_exec()?; Ok(Mmap { inner: self.inner }) } + + #[cfg(any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd", + target_os = "android" + ))] + /// Equivalent to resize_with_flag(len, libc::MREMAP_MAYMOVE) + pub fn resize(&mut self, len: usize) -> Result<()> { + self.inner.resize(len) + } + + #[cfg(any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd", + target_os = "android" + ))] + /// Corresponding to mremap() in libc, expands (or shrinks) an existing memory mapping, potentially + /// moving it at the same time (controlled by the flags argument and the available virtual address space). + /// Available flags(See mremap(2) — Linux manual page): + /// MREMAP_MAYMOVE(By default) + /// MREMAP_FIXED (since Linux 2.3.31) + /// MREMAP_DONTUNMAP (since Linux 5.7) + pub fn resize_with_flag(&mut self, len: usize, flag: libc::c_int) -> Result<()> { + self.inner.resize_with_flag(len, flag) + } } impl Deref for MmapMut { @@ -1057,4 +1082,15 @@ mod test { let mmap = mmap.make_exec().expect("make_exec"); drop(mmap); } + #[cfg(any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd", + target_os = "android" + ))] + #[test] + fn resize() { + let mut mmap = MmapMut::map_anon(256).expect("map_mut"); + mmap.resize(512).expect("resize"); + } + } diff --git a/src/unix.rs b/src/unix.rs index 4838e7e4..6fbc9fb3 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -20,7 +20,7 @@ const MAP_STACK: libc::c_int = 0; pub struct MmapInner { ptr: *mut libc::c_void, - len: usize, + len: usize } impl MmapInner { @@ -60,7 +60,7 @@ impl MmapInner { } else { Ok(MmapInner { ptr: ptr.offset(alignment as isize), - len: len, + len }) } } @@ -174,6 +174,34 @@ impl MmapInner { self.mprotect(libc::PROT_READ | libc::PROT_WRITE) } + #[cfg(any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd", + target_os = "android" + ))] + pub fn resize_with_flag(&mut self, len: usize, flag: libc::c_int) -> io::Result<()> { + unsafe { + let new_addr = libc::mremap(self.ptr, self.len, len, flag); + if new_addr == libc::MAP_FAILED { + Err(io::Error::last_os_error()) + } else { + self.ptr = new_addr; + self.len = len; + Ok(()) + } + + } + } + + #[cfg(any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd", + target_os = "android" + ))] + pub fn resize(&mut self, len: usize) -> io::Result<()> { + self.resize_with_flag(len, libc::MREMAP_MAYMOVE) + } + #[inline] pub fn ptr(&self) -> *const u8 { self.ptr as *const u8 @@ -194,14 +222,10 @@ impl Drop for MmapInner { fn drop(&mut self) { let alignment = self.ptr as usize % page_size(); unsafe { - assert!( - libc::munmap( - self.ptr.offset(-(alignment as isize)), - (self.len + alignment) as libc::size_t - ) == 0, - "unable to unmap mmap: {}", - io::Error::last_os_error() - ); + assert_eq!(libc::munmap( + self.ptr.offset(-(alignment as isize)), + (self.len + alignment) as libc::size_t + ), 0, "unable to unmap mmap: {}", io::Error::last_os_error()); } } } From 5ee2f2e67e57ef57931f6b1bf960ce62c110b735 Mon Sep 17 00:00:00 2001 From: qiujiangkun Date: Tue, 15 Sep 2020 00:02:16 +0800 Subject: [PATCH 2/3] remove resize() android condition --- src/lib.rs | 11 ++++------- src/unix.rs | 6 ++---- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 9d7ed8e7..e7753c85 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -641,8 +641,7 @@ impl MmapMut { #[cfg(any( all(target_os = "linux", not(target_arch = "mips")), - target_os = "freebsd", - target_os = "android" + target_os = "freebsd" ))] /// Equivalent to resize_with_flag(len, libc::MREMAP_MAYMOVE) pub fn resize(&mut self, len: usize) -> Result<()> { @@ -651,8 +650,7 @@ impl MmapMut { #[cfg(any( all(target_os = "linux", not(target_arch = "mips")), - target_os = "freebsd", - target_os = "android" + target_os = "freebsd" ))] /// Corresponding to mremap() in libc, expands (or shrinks) an existing memory mapping, potentially /// moving it at the same time (controlled by the flags argument and the available virtual address space). @@ -1084,8 +1082,7 @@ mod test { } #[cfg(any( all(target_os = "linux", not(target_arch = "mips")), - target_os = "freebsd", - target_os = "android" + target_os = "freebsd" ))] #[test] fn resize() { @@ -1093,4 +1090,4 @@ mod test { mmap.resize(512).expect("resize"); } -} +} \ No newline at end of file diff --git a/src/unix.rs b/src/unix.rs index 6fbc9fb3..231a3c17 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -177,7 +177,6 @@ impl MmapInner { #[cfg(any( all(target_os = "linux", not(target_arch = "mips")), target_os = "freebsd", - target_os = "android" ))] pub fn resize_with_flag(&mut self, len: usize, flag: libc::c_int) -> io::Result<()> { unsafe { @@ -194,9 +193,8 @@ impl MmapInner { } #[cfg(any( - all(target_os = "linux", not(target_arch = "mips")), - target_os = "freebsd", - target_os = "android" + all(target_os = "linux", not(target_arch = "mips"), not(target_arch = "mips")), + target_os = "freebsd" ))] pub fn resize(&mut self, len: usize) -> io::Result<()> { self.resize_with_flag(len, libc::MREMAP_MAYMOVE) From 3e234f118fbd72129d3747ab8008455f4acba851 Mon Sep 17 00:00:00 2001 From: qiujiangkun Date: Tue, 15 Sep 2020 00:15:11 +0800 Subject: [PATCH 3/3] exclude ios --- src/lib.rs | 20 ++++++++++++++------ src/unix.rs | 20 ++++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e7753c85..c96df7fe 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -639,18 +639,26 @@ impl MmapMut { Ok(Mmap { inner: self.inner }) } - #[cfg(any( - all(target_os = "linux", not(target_arch = "mips")), - target_os = "freebsd" + #[cfg( + all( + any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd" + ), + not(target_os = "ios") ))] /// Equivalent to resize_with_flag(len, libc::MREMAP_MAYMOVE) pub fn resize(&mut self, len: usize) -> Result<()> { self.inner.resize(len) } - #[cfg(any( - all(target_os = "linux", not(target_arch = "mips")), - target_os = "freebsd" + #[cfg( + all( + any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd" + ), + not(target_os = "ios") ))] /// Corresponding to mremap() in libc, expands (or shrinks) an existing memory mapping, potentially /// moving it at the same time (controlled by the flags argument and the available virtual address space). diff --git a/src/unix.rs b/src/unix.rs index 231a3c17..87f93036 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -174,9 +174,13 @@ impl MmapInner { self.mprotect(libc::PROT_READ | libc::PROT_WRITE) } - #[cfg(any( - all(target_os = "linux", not(target_arch = "mips")), - target_os = "freebsd", + #[cfg( + all( + any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd" + ), + not(target_os = "ios") ))] pub fn resize_with_flag(&mut self, len: usize, flag: libc::c_int) -> io::Result<()> { unsafe { @@ -192,9 +196,13 @@ impl MmapInner { } } - #[cfg(any( - all(target_os = "linux", not(target_arch = "mips"), not(target_arch = "mips")), - target_os = "freebsd" + #[cfg( + all( + any( + all(target_os = "linux", not(target_arch = "mips")), + target_os = "freebsd" + ), + not(target_os = "ios") ))] pub fn resize(&mut self, len: usize) -> io::Result<()> { self.resize_with_flag(len, libc::MREMAP_MAYMOVE)