use anyhow::{Context, Result};
use rustix::mm::{mprotect, MprotectFlags};
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
if len == 0 {
return Ok(());
}
unsafe {
cfg_if::cfg_if! {
if #[cfg(target_os = "linux")] {
use rustix::mm::{madvise, Advice};
if protect {
mprotect(addr.cast(), len, MprotectFlags::empty())
.context("failed to protect memory pages")?;
}
madvise(addr as _, len, Advice::LinuxDontNeed)
.context("madvise failed to decommit: {}")?;
} else {
use rustix::mm::{mmap_anonymous, ProtFlags, MapFlags};
mmap_anonymous(
addr as _,
len,
if protect {
ProtFlags::empty()
} else {
ProtFlags::READ | ProtFlags::WRITE
},
MapFlags::PRIVATE | MapFlags::FIXED,
)
.context("mmap failed to remap pages: {}")?;
}
}
}
Ok(())
}
pub fn commit_memory_pages(addr: *mut u8, len: usize) -> Result<()> {
if len == 0 {
return Ok(());
}
unsafe {
mprotect(addr.cast(), len, MprotectFlags::READ | MprotectFlags::WRITE)
.context("failed to make linear memory pages read/write")
}
}
pub fn decommit_memory_pages(addr: *mut u8, len: usize) -> Result<()> {
decommit(addr, len, true)
}
pub fn commit_table_pages(_addr: *mut u8, _len: usize) -> Result<()> {
Ok(())
}
pub fn decommit_table_pages(addr: *mut u8, len: usize) -> Result<()> {
decommit(addr, len, false)
}
#[cfg(feature = "async")]
pub fn commit_stack_pages(_addr: *mut u8, _len: usize) -> Result<()> {
Ok(())
}
#[cfg(feature = "async")]
pub fn reset_stack_pages_to_zero(addr: *mut u8, len: usize) -> Result<()> {
decommit(addr, len, false)
}