mod mr_slice;
mod perm;
mod remote;
mod slicing;
use std::io::{self, Error as IoError};
use std::ptr::NonNull;
use std::sync::Arc;
use std::{fmt, slice};
pub use self::mr_slice::*;
pub use self::perm::*;
pub use self::remote::*;
pub use self::slicing::*;
use super::pd::Pd;
use crate::bindings::*;
use crate::utils::interop::from_c_ret;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(transparent)]
pub(crate) struct IbvMr(Option<NonNull<ibv_mr>>);
impl IbvMr {
pub fn addr(&self) -> *mut u8 {
unsafe { (*self.as_ptr()).addr as *mut u8 }
}
#[allow(clippy::len_without_is_empty)]
pub fn len(&self) -> usize {
unsafe { (*self.as_ptr()).length }
}
pub fn lkey(&self) -> u32 {
unsafe { (*self.as_ptr()).lkey }
}
pub fn rkey(&self) -> u32 {
unsafe { (*self.as_ptr()).rkey }
}
pub unsafe fn dereg(self) -> io::Result<()> {
let ret = ibv_dereg_mr(self.as_ptr());
from_c_ret(ret)
}
}
impl_ibv_wrapper_traits!(ibv_mr, IbvMr);
struct MrInner {
pd: Pd,
mr: IbvMr,
}
impl Drop for MrInner {
fn drop(&mut self) {
unsafe { self.mr.dereg() }.expect("cannot dereg MR on drop");
}
}
#[derive(Clone)]
pub struct Mr {
mr: IbvMr,
inner: Arc<MrInner>,
}
impl fmt::Debug for Mr {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_fmt(format_args!("Mr<{:p}>", self.as_raw()))
}
}
impl Mr {
pub unsafe fn reg(pd: &Pd, buf: *mut u8, len: usize, perm: Permission) -> io::Result<Self> {
let mr = unsafe { ibv_reg_mr(pd.as_raw(), buf as _, len, perm.into()) };
let mr = NonNull::new(mr).ok_or_else(IoError::last_os_error)?;
let mr = IbvMr::from(mr);
Ok(Self {
inner: Arc::new(MrInner { pd: pd.clone(), mr }),
mr,
})
}
#[inline]
pub fn as_raw(&self) -> *mut ibv_mr {
self.mr.as_ptr()
}
#[inline]
pub fn lkey(&self) -> u32 {
self.mr.lkey()
}
#[inline]
pub fn rkey(&self) -> u32 {
self.mr.rkey()
}
pub fn pd(&self) -> &Pd {
&self.inner.pd
}
#[inline]
pub unsafe fn mem<'a>(&self) -> &'a mut [u8] {
slice::from_raw_parts_mut(self.addr(), self.len())
}
#[inline]
pub fn as_remote(&self) -> MrRemote {
MrRemote {
addr: self.addr() as u64,
len: self.len(),
rkey: self.rkey(),
}
}
}
unsafe impl<'s> Slicing<'s> for Mr {
type Output = MrSlice<'s>;
#[inline]
fn addr(&'s self) -> *mut u8 {
self.mr.addr()
}
#[inline]
fn len(&'s self) -> usize {
self.mr.len()
}
#[inline]
unsafe fn slice_unchecked(&'s self, offset: usize, len: usize) -> Self::Output {
MrSlice::new(self, offset, len)
}
}