#[cfg(any(target_os = "linux", target_os = "macos"))]
use core::ffi::c_void;
use core::ptr::NonNull;
#[cfg(any(target_os = "linux", target_os = "macos"))]
unsafe extern "C" {
fn mmap(
addr: *mut c_void,
length: usize,
prot: i32,
flags: i32,
fd: i32,
offset: i64,
) -> *mut c_void;
fn munmap(addr: *mut c_void, length: usize) -> i32;
fn madvise(addr: *mut c_void, length: usize, advice: i32) -> i32;
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
const PROT_READ: i32 = 0x1;
#[cfg(any(target_os = "linux", target_os = "macos"))]
const PROT_WRITE: i32 = 0x2;
#[cfg(any(target_os = "linux", target_os = "macos"))]
const MAP_PRIVATE: i32 = 0x2;
#[cfg(target_os = "linux")]
const MAP_ANONYMOUS: i32 = 0x20;
#[cfg(target_os = "macos")]
const MAP_ANONYMOUS: i32 = 0x1000;
#[cfg(target_os = "linux")]
const MADV_DISCARD: i32 = 4;
#[cfg(target_os = "macos")]
const MADV_DISCARD: i32 = 5;
pub const PAGE: usize = 4096;
#[must_use]
pub const fn round_up(n: usize, align: usize) -> usize {
(n + align - 1) & !(align - 1)
}
pub fn map_aligned(len: usize, align: usize) -> Option<NonNull<u8>> {
if len == 0 || !align.is_power_of_two() || !len.is_multiple_of(align) {
return None;
}
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
{
None
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
{
if cfg!(miri) {
return None;
}
let total = len.checked_add(align)?;
let raw = unsafe {
mmap(
core::ptr::null_mut(),
total,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS,
-1,
0,
)
};
if raw as isize == -1 {
return None;
}
NonNull::new(trim(raw as usize, total, len, align) as *mut u8)
}
}
#[cfg(any(target_os = "linux", target_os = "macos"))]
fn trim(raw: usize, total: usize, len: usize, align: usize) -> usize {
let start = (raw + align - 1) & !(align - 1);
let prefix = start - raw;
let suffix = total - prefix - len;
if prefix > 0 {
unsafe { munmap(raw as *mut c_void, prefix) };
}
if suffix > 0 {
unsafe { munmap((start + len) as *mut c_void, suffix) };
}
start
}
pub unsafe fn unmap(ptr: NonNull<u8>, len: usize) {
#[cfg(any(target_os = "linux", target_os = "macos"))]
{
if cfg!(miri) {
return;
}
unsafe { munmap(ptr.as_ptr().cast(), len) };
}
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
{
let _ = (ptr, len);
}
}
pub unsafe fn discard(ptr: NonNull<u8>, len: usize) -> bool {
#[cfg(any(target_os = "linux", target_os = "macos"))]
{
if cfg!(miri) {
return false;
}
unsafe { madvise(ptr.as_ptr().cast(), len, MADV_DISCARD) == 0 }
}
#[cfg(not(any(target_os = "linux", target_os = "macos")))]
{
let _ = (ptr, len);
false
}
}
#[must_use]
pub const fn available() -> bool {
cfg!(any(target_os = "linux", target_os = "macos")) && !cfg!(miri)
}