use clippy_utilities::OverflowArithmetic;
use super::{raw::RawMemoryRegion, MrAccess};
use std::{fmt::Debug, io, ops::Range, slice, sync::Arc};
pub trait LocalMrReadAccess: MrAccess {
#[inline]
#[allow(clippy::as_conversions)]
fn as_ptr(&self) -> *const u8 {
self.addr() as _
}
#[inline]
fn as_slice(&self) -> &[u8] {
unsafe { slice::from_raw_parts(self.as_ptr(), self.length()) }
}
fn lkey(&self) -> u32;
}
pub trait LocalMrWriteAccess: MrAccess + LocalMrReadAccess {
#[inline]
#[allow(clippy::as_conversions)]
fn as_mut_ptr(&mut self) -> *mut u8 {
self.as_ptr() as _
}
#[inline]
fn as_mut_slice(&mut self) -> &mut [u8] {
unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.length()) }
}
}
#[derive(Debug)]
pub struct LocalMr {
addr: usize,
len: usize,
raw: Arc<RawMemoryRegion>,
}
impl MrAccess for LocalMr {
#[inline]
fn addr(&self) -> usize {
self.addr
}
#[inline]
fn length(&self) -> usize {
self.len
}
#[inline]
fn rkey(&self) -> u32 {
self.raw.lkey()
}
}
impl LocalMrReadAccess for LocalMr {
#[inline]
fn lkey(&self) -> u32 {
self.raw.lkey()
}
}
impl LocalMrWriteAccess for LocalMr {}
impl LocalMr {
pub(crate) fn new(addr: usize, len: usize, raw: Arc<RawMemoryRegion>) -> Self {
Self { addr, len, raw }
}
#[inline]
pub fn get(&self, i: Range<usize>) -> io::Result<LocalMrSlice> {
if i.start >= i.end || i.end > self.length() {
Err(io::Error::new(io::ErrorKind::Other, "wrong range of lmr"))
} else {
Ok(LocalMrSlice::new(
self,
self.addr().overflow_add(i.start),
i.len(),
))
}
}
#[inline]
pub fn get_mut(&mut self, i: Range<usize>) -> io::Result<LocalMrSliceMut> {
if i.start >= i.end || i.end > self.length() {
Err(io::Error::new(io::ErrorKind::Other, "wrong range of lmr"))
} else {
Ok(LocalMrSliceMut::new(
self,
self.addr().overflow_add(i.start),
i.len(),
))
}
}
#[inline]
pub(crate) fn take(mut self, i: Range<usize>) -> io::Result<Self> {
if i.start >= i.end || i.end > self.length() {
Err(io::Error::new(io::ErrorKind::Other, "wrong range of lmr"))
} else {
self.addr = self.addr.overflow_add(i.start);
self.len = i.end.overflow_sub(i.start);
Ok(self)
}
}
}
impl MrAccess for &LocalMr {
#[inline]
fn addr(&self) -> usize {
self.addr
}
#[inline]
fn length(&self) -> usize {
self.len
}
#[inline]
fn rkey(&self) -> u32 {
self.raw.rkey()
}
}
impl LocalMrReadAccess for &LocalMr {
#[inline]
fn lkey(&self) -> u32 {
self.raw.lkey()
}
}
#[derive(Debug)]
pub struct LocalMrSlice<'a> {
lmr: &'a LocalMr,
addr: usize,
len: usize,
}
impl MrAccess for LocalMrSlice<'_> {
#[inline]
fn addr(&self) -> usize {
self.addr
}
#[inline]
fn length(&self) -> usize {
self.len
}
#[inline]
fn rkey(&self) -> u32 {
self.lmr.rkey()
}
}
impl LocalMrReadAccess for LocalMrSlice<'_> {
fn lkey(&self) -> u32 {
self.lmr.lkey()
}
}
impl<'a> LocalMrSlice<'a> {
pub(crate) fn new(lmr: &'a LocalMr, addr: usize, len: usize) -> Self {
Self { lmr, addr, len }
}
}
#[derive(Debug)]
pub struct LocalMrSliceMut<'a> {
lmr: &'a mut LocalMr,
addr: usize,
len: usize,
}
impl<'a> LocalMrSliceMut<'a> {
pub(crate) fn new(lmr: &'a mut LocalMr, addr: usize, len: usize) -> Self {
Self { lmr, addr, len }
}
}
impl MrAccess for LocalMrSliceMut<'_> {
#[inline]
fn addr(&self) -> usize {
self.addr
}
#[inline]
fn length(&self) -> usize {
self.len
}
#[inline]
fn rkey(&self) -> u32 {
self.lmr.rkey()
}
}
impl LocalMrReadAccess for LocalMrSliceMut<'_> {
fn lkey(&self) -> u32 {
self.lmr.lkey()
}
}
impl LocalMrWriteAccess for LocalMrSliceMut<'_> {}