mod mmap;
use mmap::Mmap;
use std::{
io,
num::NonZeroU32,
ptr::NonNull,
slice,
sync::{Arc, Mutex},
};
use super::{
FrameLayout,
frame::{Data, DataMut, FrameDesc, Headroom, HeadroomMut},
};
#[derive(Clone, Debug)]
pub struct UmemRegion {
layout: FrameLayout,
addr: NonNull<libc::c_void>,
len: usize,
_mmap: Arc<Mutex<Mmap>>,
}
unsafe impl Send for UmemRegion {}
unsafe impl Sync for UmemRegion {}
impl UmemRegion {
pub(super) fn new(
frame_count: NonZeroU32,
frame_layout: FrameLayout,
use_huge_pages: bool,
) -> io::Result<Self> {
let len = (frame_count.get() as usize) * frame_layout.frame_size();
let mmap = Mmap::new(len, use_huge_pages)?;
Ok(Self {
layout: frame_layout,
addr: mmap.addr(),
len,
_mmap: Arc::new(Mutex::new(mmap)),
})
}
#[inline]
pub fn len(&self) -> usize {
self.len
}
#[inline]
pub fn as_ptr(&self) -> *mut libc::c_void {
self.addr.as_ptr()
}
#[inline]
unsafe fn headroom_ptr(&self, desc: &FrameDesc) -> *mut u8 {
let addr = desc.addr - self.layout.frame_headroom;
unsafe { self.as_ptr().add(addr) as *mut u8 }
}
#[inline]
unsafe fn data_ptr(&self, desc: &FrameDesc) -> *mut u8 {
unsafe { self.as_ptr().add(desc.addr) as *mut u8 }
}
#[inline]
pub unsafe fn frame(&self, desc: &FrameDesc) -> (Headroom<'_>, Data<'_>) {
unsafe { (self.headroom(desc), self.data(desc)) }
}
#[inline]
pub unsafe fn headroom(&self, desc: &FrameDesc) -> Headroom<'_> {
let headroom_ptr = unsafe { self.headroom_ptr(desc) };
Headroom::new(unsafe { slice::from_raw_parts(headroom_ptr, desc.lengths.headroom) })
}
#[inline]
pub unsafe fn data(&self, desc: &FrameDesc) -> Data<'_> {
let data_ptr = unsafe { self.data_ptr(desc) };
Data::new(unsafe { slice::from_raw_parts(data_ptr, desc.lengths.data) })
}
#[inline]
pub unsafe fn frame_mut<'a>(
&'a self,
desc: &'a mut FrameDesc,
) -> (HeadroomMut<'a>, DataMut<'a>) {
let headroom_ptr = unsafe { self.headroom_ptr(desc) };
let data_ptr = unsafe { self.data_ptr(desc) };
let headroom =
unsafe { slice::from_raw_parts_mut(headroom_ptr, self.layout.frame_headroom) };
let data = unsafe { slice::from_raw_parts_mut(data_ptr, self.layout.mtu) };
(
HeadroomMut::new(&mut desc.lengths.headroom, headroom),
DataMut::new(&mut desc.lengths.data, data),
)
}
#[inline]
pub unsafe fn headroom_mut<'a>(&'a self, desc: &'a mut FrameDesc) -> HeadroomMut<'a> {
let headroom_ptr = unsafe { self.headroom_ptr(desc) };
let headroom =
unsafe { slice::from_raw_parts_mut(headroom_ptr, self.layout.frame_headroom) };
HeadroomMut::new(&mut desc.lengths.headroom, headroom)
}
#[inline]
pub unsafe fn data_mut<'a>(&'a self, desc: &'a mut FrameDesc) -> DataMut<'a> {
let data_ptr = unsafe { self.data_ptr(desc) };
let data = unsafe { slice::from_raw_parts_mut(data_ptr, self.layout.mtu) };
DataMut::new(&mut desc.lengths.data, data)
}
}