use super::{IbvAccess, MrAccess, MrToken};
use crate::agent::AgentInner;
use rdma_sys::ibv_access_flags;
use std::{io, ops::Range, sync::Arc, time::SystemTime};
use tracing::debug;
pub trait RemoteMrReadAccess: MrAccess {
#[inline]
fn timeout_check(&self) -> bool {
SystemTime::now() >= self.token().ddl
}
fn token(&self) -> MrToken;
}
pub trait RemoteMrWriteAccess: MrAccess + RemoteMrReadAccess {}
#[derive(Debug)]
pub struct RemoteMr {
token: MrToken,
agent: Option<Arc<AgentInner>>,
}
impl MrAccess for RemoteMr {
#[inline]
fn addr(&self) -> usize {
self.token.addr
}
#[inline]
fn length(&self) -> usize {
self.token.len
}
#[inline]
fn rkey(&self) -> u32 {
self.token.rkey
}
}
impl IbvAccess for RemoteMr {
#[inline]
fn ibv_access(&self) -> ibv_access_flags {
ibv_access_flags(self.token.access)
}
}
impl RemoteMrReadAccess for RemoteMr {
#[inline]
fn token(&self) -> MrToken {
self.token
}
}
impl RemoteMrWriteAccess for RemoteMr {}
impl Drop for RemoteMr {
#[inline]
fn drop(&mut self) {
self.agent.as_ref().map_or_else(
|| debug!("drop a rmr created by user"),
|agent| {
let agent = Arc::<AgentInner>::clone(agent);
let token = self.token;
let _task =
tokio::spawn(async move { AgentInner::release_mr(&agent, token).await });
},
);
}
}
impl RemoteMr {
#[inline]
pub(crate) fn new_from_token(token: MrToken, agent: Option<Arc<AgentInner>>) -> Self {
Self { token, agent }
}
#[inline]
#[must_use]
pub fn new(token: MrToken) -> Self {
Self::new_from_token(token, None)
}
#[inline]
pub fn get(&self, i: Range<usize>) -> io::Result<RemoteMrSlice> {
if i.start >= i.end || i.end > self.length() {
Err(io::Error::new(io::ErrorKind::Other, "wrong range of rmr"))
} else {
let slice_token = MrToken {
addr: self.addr().wrapping_add(i.start),
len: i.end.wrapping_sub(i.start),
rkey: self.rkey(),
ddl: self.token.ddl,
access: self.ibv_access().0,
};
Ok(RemoteMrSlice::new_from_token(self, slice_token))
}
}
#[inline]
pub fn get_mut(&mut self, i: Range<usize>) -> io::Result<RemoteMrSliceMut> {
if i.start >= i.end || i.end > self.length() {
Err(io::Error::new(io::ErrorKind::Other, "wrong range of rmr"))
} else {
let slice_token = MrToken {
addr: self.addr().wrapping_add(i.start),
len: i.end.wrapping_sub(i.start),
rkey: self.rkey(),
ddl: self.token.ddl,
access: self.ibv_access().0,
};
Ok(RemoteMrSliceMut::new_from_token(self, slice_token))
}
}
}
impl MrAccess for &RemoteMr {
#[inline]
fn addr(&self) -> usize {
self.token.addr
}
#[inline]
fn length(&self) -> usize {
self.token.len
}
#[inline]
fn rkey(&self) -> u32 {
self.token.rkey
}
}
impl IbvAccess for &RemoteMr {
#[inline]
fn ibv_access(&self) -> ibv_access_flags {
ibv_access_flags(self.token.access)
}
}
impl RemoteMrReadAccess for &RemoteMr {
#[inline]
fn token(&self) -> MrToken {
self.token
}
}
impl MrAccess for &mut RemoteMr {
#[inline]
fn addr(&self) -> usize {
self.token.addr
}
#[inline]
fn length(&self) -> usize {
self.token.len
}
#[inline]
fn rkey(&self) -> u32 {
self.token.rkey
}
}
impl IbvAccess for &mut RemoteMr {
#[inline]
fn ibv_access(&self) -> ibv_access_flags {
ibv_access_flags(self.token.access)
}
}
impl RemoteMrReadAccess for &mut RemoteMr {
#[inline]
fn token(&self) -> MrToken {
self.token
}
}
impl RemoteMrWriteAccess for &mut RemoteMr {}
#[derive(Debug)]
pub struct RemoteMrSlice<'a> {
#[allow(dead_code)]
rmr: &'a RemoteMr,
token: MrToken,
}
impl<'a> RemoteMrSlice<'a> {
#[inline]
pub(crate) fn new_from_token(rmr: &'a RemoteMr, token: MrToken) -> Self {
Self { rmr, token }
}
}
impl MrAccess for RemoteMrSlice<'_> {
#[inline]
fn addr(&self) -> usize {
self.token.addr
}
#[inline]
fn length(&self) -> usize {
self.token.len
}
#[inline]
fn rkey(&self) -> u32 {
self.token.rkey
}
}
impl IbvAccess for RemoteMrSlice<'_> {
#[inline]
fn ibv_access(&self) -> ibv_access_flags {
ibv_access_flags(self.token.access)
}
}
impl RemoteMrReadAccess for RemoteMrSlice<'_> {
fn token(&self) -> MrToken {
self.token
}
}
#[derive(Debug)]
pub struct RemoteMrSliceMut<'a> {
#[allow(dead_code)]
rmr: &'a mut RemoteMr,
token: MrToken,
}
impl MrAccess for RemoteMrSliceMut<'_> {
#[inline]
fn addr(&self) -> usize {
self.token.addr
}
#[inline]
fn length(&self) -> usize {
self.token.len
}
#[inline]
fn rkey(&self) -> u32 {
self.token.rkey
}
}
impl IbvAccess for RemoteMrSliceMut<'_> {
#[inline]
fn ibv_access(&self) -> ibv_access_flags {
ibv_access_flags(self.token.access)
}
}
impl<'a> RemoteMrSliceMut<'a> {
#[inline]
pub(crate) fn new_from_token(rmr: &'a mut RemoteMr, token: MrToken) -> Self {
Self { rmr, token }
}
}
impl RemoteMrReadAccess for RemoteMrSliceMut<'_> {
fn token(&self) -> MrToken {
self.token
}
}
impl RemoteMrWriteAccess for RemoteMrSliceMut<'_> {}