use core::ptr;
#[inline(never)]
pub unsafe fn memset_volatile<T>(dst: *mut T, src: T, len: usize)
where
T: Copy + Sized,
{
for idx in 0..len {
let ptr = unsafe { dst.add(idx) };
unsafe {
ptr::write_volatile(ptr, src);
}
}
}
#[inline]
pub fn memset_slice_volatile<T>(slice: &mut [T], src: T)
where
T: Copy + Sized,
{
let len = slice.len();
let dst = slice.as_mut_ptr().cast();
unsafe {
memset_volatile(dst, src, len);
}
}
#[inline]
pub unsafe fn mlock(_addr: *mut u8, _len: usize) -> crate::Result<()> {
#[cfg(feature = "libc")]
{
let mlock = unsafe { libc::mlock(_addr.cast(), _len) };
if mlock != 0 {
return Err(crate::Error::MlockError);
}
Ok(())
}
#[cfg(not(feature = "libc"))]
return Err(crate::Error::UnsupportedMlockPlatform);
}
#[inline]
pub fn mlock_slice(_slice: &mut [u8]) -> crate::Result<()> {
#[cfg(not(miri))]
unsafe {
let len = _slice.len();
mlock(_slice.as_mut_ptr(), len)?;
}
Ok(())
}
#[inline]
pub unsafe fn munlock(_addr: *mut u8, _len: usize) -> crate::Result<()> {
#[cfg(feature = "libc")]
{
let munlock = unsafe { libc::munlock(_addr.cast(), _len) };
if munlock != 0 {
return Err(crate::Error::MunlockError);
}
Ok(())
}
#[cfg(not(feature = "libc"))]
return Err(crate::Error::UnsupportedMlockPlatform);
}
#[inline]
pub fn munlock_slice(_slice: &mut [u8]) -> crate::Result<()> {
#[cfg(not(miri))]
unsafe {
let len = _slice.len();
munlock(_slice.as_mut_ptr(), len)?;
}
Ok(())
}
#[cfg(all(feature = "libc", test))]
mod tests {
use crate::{
collection::Vector,
misc::{mlock, mlock_slice, munlock, munlock_slice},
};
#[test]
fn mlock_and_munlock() {
let mut data = Vector::with_capacity(1024).unwrap();
unsafe {
mlock(data.as_mut_ptr(), data.capacity()).unwrap();
}
unsafe {
munlock(data.as_mut_ptr(), data.capacity()).unwrap();
}
}
#[test]
fn mlock_and_munlock_slice() {
let mut data = [1, 2, 3, 4];
mlock_slice(&mut data).unwrap();
munlock_slice(&mut data).unwrap();
}
}