Skip to main content

machina_memory/
ram.rs

1use std::ptr;
2
3/// mmap-backed host memory allocation.
4///
5/// Owns a contiguous region of anonymous memory obtained via
6/// `mmap(MAP_PRIVATE | MAP_ANONYMOUS)`.  Freed on drop.
7pub struct RamBlock {
8    ptr: *mut u8,
9    size: u64,
10}
11
12impl RamBlock {
13    pub fn new(size: u64) -> Self {
14        // SAFETY: mmap with MAP_ANONYMOUS returns a fresh
15        // zero-filled mapping or MAP_FAILED.
16        let ptr = unsafe {
17            libc::mmap(
18                ptr::null_mut(),
19                size as usize,
20                libc::PROT_READ | libc::PROT_WRITE,
21                libc::MAP_PRIVATE | libc::MAP_ANONYMOUS,
22                -1,
23                0,
24            ) as *mut u8
25        };
26        assert!(
27            !ptr.is_null() && ptr != libc::MAP_FAILED as *mut u8,
28            "mmap failed for size {size}"
29        );
30        Self { ptr, size }
31    }
32
33    pub fn as_ptr(&self) -> *mut u8 {
34        self.ptr
35    }
36
37    pub fn size(&self) -> u64 {
38        self.size
39    }
40}
41
42// SAFETY: The mmap'd memory is exclusively owned by this
43// RamBlock instance; no aliasing pointers exist.
44unsafe impl Send for RamBlock {}
45unsafe impl Sync for RamBlock {}
46
47impl Drop for RamBlock {
48    fn drop(&mut self) {
49        // SAFETY: ptr/size were produced by a successful mmap
50        // in `new` and have not been modified since.
51        unsafe {
52            libc::munmap(self.ptr as *mut libc::c_void, self.size as usize);
53        }
54    }
55}