Files
wasmtime/crates/runtime/src/instance/allocator/pooling/unix.rs
Dan Gohman 47490b4383 Use rsix to make system calls in Wasmtime. (#3355)
* Use rsix to make system calls in Wasmtime.

`rsix` is a system call wrapper crate that we use in `wasi-common`,
which can provide the following advantages in the rest of Wasmtime:

 - It eliminates some `unsafe` blocks in Wasmtime's code. There's
   still an `unsafe` block in the library, but this way, the `unsafe`
   is factored out and clearly scoped.

 - And, it makes error handling more consistent, factoring out code for
   checking return values and `io::Error::last_os_error()`, and code that
   does `errno::set_errno(0)`.

This doesn't cover *all* system calls; `rsix` doesn't implement
signal-handling APIs, and this doesn't cover calls made through `std` or
crates like `userfaultfd`, `rand`, and `region`.
2021-09-17 15:28:56 -07:00

64 lines
1.7 KiB
Rust

use anyhow::{Context, Result};
fn decommit(addr: *mut u8, len: usize, protect: bool) -> Result<()> {
if len == 0 {
return Ok(());
}
// By creating a new mapping at the same location, this will discard the
// mapping for the pages in the given range.
// The new mapping will be to the CoW zero page, so this effectively
// zeroes the pages.
unsafe {
rsix::io::mmap_anonymous(
addr as _,
len,
if protect {
rsix::io::ProtFlags::NONE
} else {
rsix::io::ProtFlags::READ | rsix::io::ProtFlags::WRITE
},
rsix::io::MapFlags::PRIVATE | rsix::io::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(());
}
// Just change the protection level to READ|WRITE
unsafe {
region::protect(addr, len, region::Protection::READ_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<()> {
// A no-op as table pages remain READ|WRITE
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<()> {
// A no-op as stack pages remain READ|WRITE
Ok(())
}
#[cfg(feature = "async")]
pub fn decommit_stack_pages(addr: *mut u8, len: usize) -> Result<()> {
decommit(addr, len, false)
}