use libc::{c_int, mlockall};
use libc::{EAGAIN, EINVAL, ENOMEM, EPERM};
use libc::{MCL_CURRENT, MCL_FUTURE};
use crate::errno::errno;
use crate::error::{Error, Result};
extern "C" {
pub static _MCL_ONFAULT: libc::c_int;
}
pub fn _mlockall_wrapper(flags: c_int) -> Result<()> {
let err = unsafe { mlockall(flags) };
if err == 0 {
return Ok(());
}
Err(match errno() {
EAGAIN => Error::CouldNotLockMemory,
EINVAL => Error::InvalidFlags,
ENOMEM => Error::TooMuchMemoryToLock,
EPERM => Error::NoPermission,
_ => Error::UnknownMlockall,
})
}
pub fn lock_memory_pages() -> Result<()> {
#[allow(non_snake_case)]
let MCL_ONFAULT: c_int = unsafe { _MCL_ONFAULT };
match _mlockall_wrapper(MCL_CURRENT | MCL_FUTURE | MCL_ONFAULT) {
Err(err) => {
eprintln!("First try at mlockall failed: {:?}", err);
}
Ok(_) => return Ok(()),
}
_mlockall_wrapper(MCL_CURRENT | MCL_FUTURE)
}