use super::empty_mmap;
use crate::{send_sync_ptr::SendSyncPtr, traits::Reset};
use eyre::Result;
use rustix::mm::{self, MapFlags, ProtFlags};
use std::ptr::{self, NonNull};
#[repr(C)]
pub struct MmapOffset {
mmap: Mmap,
pub offset: usize,
}
impl MmapOffset {
pub fn new_empty() -> Self {
let emptry = Mmap::new_empty();
Self {
mmap: emptry,
offset: 0,
}
}
pub fn new(size: usize) -> Result<Self> {
let mmap = Mmap::new(size)?;
Ok(Self { mmap, offset: 0 })
}
}
impl Reset for MmapOffset {
fn reset(&mut self) {
self.offset = 0;
}
}
#[derive(Debug)]
pub struct Mmap {
memory: SendSyncPtr<[u8]>,
}
impl Mmap {
pub fn new_empty() -> Self {
Self {
memory: empty_mmap(),
}
}
pub fn new(size: usize) -> Result<Self> {
let ptr = unsafe {
mm::mmap_anonymous(
ptr::null_mut(),
size,
ProtFlags::READ | ProtFlags::WRITE,
MapFlags::PRIVATE | MapFlags::NORESERVE,
)?
};
let memory = std::ptr::slice_from_raw_parts_mut(ptr.cast(), size);
let memory = SendSyncPtr::new(NonNull::new(memory).unwrap());
Ok(Self { memory })
}
pub fn is_empty(&self) -> bool {
self.memory.as_non_null().is_empty()
}
}
impl Drop for Mmap {
fn drop(&mut self) {
unsafe {
let ptr = self.memory.as_ptr().cast();
let len = self.memory.len();
if len == 0 {
return;
}
rustix::mm::munmap(ptr, len).expect("munmap failed");
}
}
}