// newtype pattern,就是一个u64位的地址,在此基础上增加了一些utils方法
pub struct GuestAddress(pub u64);
use crate::{platform::MemoryMapping as SysUtilMmap}
pub struct MemoryMapping {
mapping: SysUtilMmap,
}
// 底层会调用mmap分配内存,
// SysUtilMmap
pub struct MemoryMapping {
addr: *mut u8,
size: usize,
}
pub struct MemoryRegion {
mapping: MemoryMapping,
guest_base: GuestAddress,
shared_obj: BackingObject,
obj_offset: u64,
}
// 就是多个MemoryRegion,每一个MemoryRegion就是一个mmap,可以share memory,
// 也可以是file mapping
pub struct GuestMemory {
regions: Arc<[MemoryRegion]>,
}
告诉内核这段内存使用hutgepage
pub fn use_hugepages(&self) -> Result<()> {
const SZ_2M: usize = 2 * 1024 * 1024;
// THP uses 2M pages, so use THP only on mappings that are at least
// 2M in size.
if self.size() < SZ_2M {
return Ok(());
}
// This is safe because we call madvise with a valid address and size, and we check the
// return value.
let ret = unsafe {
libc::madvise(
self.as_ptr() as *mut libc::c_void,
self.size(),
libc::MADV_HUGEPAGE,
)
};
if ret == -1 {
Err(Error::SystemCallFailed(ErrnoError::last()))
} else {
Ok(())
}
}
私有文件映射是不需要的,任何变更都只是在内存中,不用同步到文件,但是共享文件映射需要在unmap之前通过msync同步到文件中。
/// Calls msync with MS_SYNC on the mapping.
pub fn msync(&self) -> Result<()> {
// This is safe since we use the exact address and length of a known
// good memory mapping.
let ret = unsafe {
libc::msync(
self.as_ptr() as *mut libc::c_void,
self.size(),
libc::MS_SYNC,
)
};
if ret == -1 {
return Err(Error::SystemCallFailed(ErrnoError::last()));
}
Ok(())
}
pub struct MemoryMapping {
addr: *mut u8,
size: usize,
}
// Send and Sync aren't automatically inherited for the raw address pointer.
// Accessing that pointer is only done through the stateless interface which
// allows the object to be shared by multiple threads without a decrease in
// safety.
unsafe impl Send for MemoryMapping {}
unsafe impl Sync for MemoryMapping {}