allocate big mmap with unreserved memory
This commit is contained in:
parent
1d142ea8b0
commit
b6187890b0
|
@ -49,7 +49,8 @@ impl Mmap {
|
||||||
// `MAP_ANON` - mapping is not backed by any file and initial contents are
|
// `MAP_ANON` - mapping is not backed by any file and initial contents are
|
||||||
// initialized to zero.
|
// initialized to zero.
|
||||||
// `MAP_PRIVATE` - the mapping is private to this process.
|
// `MAP_PRIVATE` - the mapping is private to this process.
|
||||||
libc::MAP_ANON | libc::MAP_PRIVATE,
|
// `MAP_NORESERVE` - do not reserve swap space for this mapping.
|
||||||
|
libc::MAP_ANON | libc::MAP_PRIVATE | libc::MAP_NORESERVE,
|
||||||
// `fildes` - a file descriptor. Pass -1 as this is required for some platforms
|
// `fildes` - a file descriptor. Pass -1 as this is required for some platforms
|
||||||
// when the `MAP_ANON` is passed.
|
// when the `MAP_ANON` is passed.
|
||||||
-1,
|
-1,
|
||||||
|
@ -120,66 +121,59 @@ impl Drop for Mmap {
|
||||||
|
|
||||||
pub struct ByteBuf {
|
pub struct ByteBuf {
|
||||||
mmap: Option<Mmap>,
|
mmap: Option<Mmap>,
|
||||||
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: we either make this an arbitrarily large value and use MAP_NORESERVE
|
||||||
|
// (which means we can segfault when writing instead of the allocation
|
||||||
|
// failing). or we need to figure out the maximum mem + swap available.
|
||||||
|
const MMAP_SIZE: usize = 2 << 40;
|
||||||
|
|
||||||
impl ByteBuf {
|
impl ByteBuf {
|
||||||
pub fn new(len: usize) -> Result<Self, &'static str> {
|
pub fn new(len: usize) -> Result<Self, &'static str> {
|
||||||
let mmap = if len == 0 {
|
let mmap = if len == 0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
Some(Mmap::new(len)?)
|
Some(Mmap::new(MMAP_SIZE)?)
|
||||||
};
|
};
|
||||||
Ok(Self { mmap })
|
|
||||||
|
Ok(Self { mmap, len })
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn realloc(&mut self, new_len: usize) -> Result<(), &'static str> {
|
pub fn realloc(&mut self, new_len: usize) -> Result<(), &'static str> {
|
||||||
let new_mmap = if new_len == 0 {
|
if new_len == 0 {
|
||||||
None
|
self.mmap = None
|
||||||
} else {
|
} else if let None = self.mmap {
|
||||||
if self.len() == 0 {
|
self.mmap = Some(Mmap::new(MMAP_SIZE)?)
|
||||||
Some(Mmap::new(new_len)?)
|
|
||||||
} else {
|
|
||||||
let mut new_mmap = Mmap::new(new_len)?;
|
|
||||||
|
|
||||||
{
|
|
||||||
let src = self
|
|
||||||
.mmap
|
|
||||||
.as_ref()
|
|
||||||
.expect(
|
|
||||||
"self.len() != 0;
|
|
||||||
self.mmap is created if self.len() != 0;
|
|
||||||
self.mmap is not `None`;
|
|
||||||
qed",
|
|
||||||
)
|
|
||||||
.as_slice();
|
|
||||||
let dst = new_mmap.as_slice_mut();
|
|
||||||
dst[..src.len()].copy_from_slice(src);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Some(new_mmap)
|
self.len = new_len;
|
||||||
}
|
|
||||||
};
|
|
||||||
self.mmap = new_mmap;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn len(&self) -> usize {
|
pub fn len(&self) -> usize {
|
||||||
self.mmap.as_ref().map(|m| m.len).unwrap_or(0)
|
self.len
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
self.mmap.as_ref().map(|m| m.as_slice()).unwrap_or(&[])
|
let len = self.len();
|
||||||
|
self.mmap
|
||||||
|
.as_ref()
|
||||||
|
.map(|m| m.as_slice().split_at(len).0)
|
||||||
|
.unwrap_or(&[])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_slice_mut(&mut self) -> &mut [u8] {
|
pub fn as_slice_mut(&mut self) -> &mut [u8] {
|
||||||
|
let len = self.len();
|
||||||
self.mmap
|
self.mmap
|
||||||
.as_mut()
|
.as_mut()
|
||||||
.map(|m| m.as_slice_mut())
|
.map(|m| m.as_slice_mut().split_at_mut(len).0)
|
||||||
.unwrap_or(&mut [])
|
.unwrap_or(&mut [])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn erase(&mut self) -> Result<(), &'static str> {
|
pub fn erase(&mut self) -> Result<(), &'static str> {
|
||||||
let cur_len = match self.mmap {
|
match self.mmap {
|
||||||
// Nothing to do here...
|
// Nothing to do here...
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
Some(Mmap { len: cur_len, .. }) => cur_len,
|
Some(Mmap { len: cur_len, .. }) => cur_len,
|
||||||
|
@ -192,7 +186,7 @@ impl ByteBuf {
|
||||||
//
|
//
|
||||||
// Otherwise we double the peak memory consumption.
|
// Otherwise we double the peak memory consumption.
|
||||||
self.mmap = None;
|
self.mmap = None;
|
||||||
self.mmap = Some(Mmap::new(cur_len)?);
|
self.mmap = Some(Mmap::new(MMAP_SIZE)?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue