use alloc::sync::Arc;
use bytemuck::Pod;
pub unsafe trait MemOps {
type Error;
fn read(&self, addr: u64, dst: &mut [u8]) -> Result<(), Self::Error>;
fn write(&self, addr: u64, src: &[u8]) -> Result<(), Self::Error>;
fn load_acquire(&self, addr: u64) -> Result<u16, Self::Error>;
fn store_release(&self, addr: u64, val: u16) -> Result<(), Self::Error>;
unsafe fn as_slice(&self, addr: u64, len: usize) -> Result<&[u8], Self::Error>;
#[allow(clippy::mut_from_ref)]
unsafe fn as_mut_slice(&self, addr: u64, len: usize) -> Result<&mut [u8], Self::Error>;
fn read_val<T: Pod>(&self, addr: u64) -> Result<T, Self::Error> {
let mut val = T::zeroed();
let bytes = bytemuck::bytes_of_mut(&mut val);
self.read(addr, bytes)?;
Ok(val)
}
fn write_val<T: Pod>(&self, addr: u64, val: T) -> Result<(), Self::Error> {
let bytes = bytemuck::bytes_of(&val);
self.write(addr, bytes)?;
Ok(())
}
}
unsafe impl<T: MemOps> MemOps for Arc<T> {
type Error = T::Error;
fn read(&self, addr: u64, dst: &mut [u8]) -> Result<(), Self::Error> {
(**self).read(addr, dst)
}
fn write(&self, addr: u64, src: &[u8]) -> Result<(), Self::Error> {
(**self).write(addr, src)
}
fn load_acquire(&self, addr: u64) -> Result<u16, Self::Error> {
(**self).load_acquire(addr)
}
fn store_release(&self, addr: u64, val: u16) -> Result<(), Self::Error> {
(**self).store_release(addr, val)
}
unsafe fn as_slice(&self, addr: u64, len: usize) -> Result<&[u8], Self::Error> {
unsafe { (**self).as_slice(addr, len) }
}
#[allow(clippy::mut_from_ref)]
unsafe fn as_mut_slice(&self, addr: u64, len: usize) -> Result<&mut [u8], Self::Error> {
unsafe { (**self).as_mut_slice(addr, len) }
}
}