Update CodeMemory to be Send + Sync (#780)
* Update `CodeMemory` to be `Send + Sync` This commit updates the `CodeMemory` type in wasmtime to be both `Send` and `Sync` by updating the implementation of `Mmap` to not store raw pointers. This avoids the need for an `unsafe impl` and leaves the unsafety as it is currently. * Run rustfmt * Rename `offset` to `ptr`
This commit is contained in:
@@ -14,6 +14,11 @@ pub struct CodeMemory {
|
|||||||
published: usize,
|
published: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _assert() {
|
||||||
|
fn _assert_send_sync<T: Send + Sync>() {}
|
||||||
|
_assert_send_sync::<CodeMemory>();
|
||||||
|
}
|
||||||
|
|
||||||
impl CodeMemory {
|
impl CodeMemory {
|
||||||
/// Create a new `CodeMemory` instance.
|
/// Create a new `CodeMemory` instance.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
|
|||||||
@@ -1,11 +1,8 @@
|
|||||||
//! Low-level abstraction for allocating and managing zero-filled pages
|
//! Low-level abstraction for allocating and managing zero-filled pages
|
||||||
//! of memory.
|
//! of memory.
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
|
||||||
use libc;
|
|
||||||
use more_asserts::assert_le;
|
use more_asserts::assert_le;
|
||||||
use more_asserts::assert_lt;
|
use more_asserts::assert_lt;
|
||||||
use region;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
@@ -19,7 +16,11 @@ fn round_up_to_page_size(size: usize, page_size: usize) -> usize {
|
|||||||
/// and initially-zeroed memory and a length.
|
/// and initially-zeroed memory and a length.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Mmap {
|
pub struct Mmap {
|
||||||
ptr: *mut u8,
|
// Note that this is stored as a `usize` instead of a `*const` or `*mut`
|
||||||
|
// pointer to allow this structure to be natively `Send` and `Sync` without
|
||||||
|
// `unsafe impl`. This type is sendable across threads and shareable since
|
||||||
|
// the coordination all happens at the OS layer.
|
||||||
|
ptr: usize,
|
||||||
len: usize,
|
len: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,8 +30,9 @@ impl Mmap {
|
|||||||
// Rust's slices require non-null pointers, even when empty. `Vec`
|
// Rust's slices require non-null pointers, even when empty. `Vec`
|
||||||
// contains code to create a non-null dangling pointer value when
|
// contains code to create a non-null dangling pointer value when
|
||||||
// constructed empty, so we reuse that here.
|
// constructed empty, so we reuse that here.
|
||||||
|
let empty = Vec::<u8>::new();
|
||||||
Self {
|
Self {
|
||||||
ptr: Vec::new().as_mut_ptr(),
|
ptr: empty.as_ptr() as usize,
|
||||||
len: 0,
|
len: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -78,7 +80,7 @@ impl Mmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ptr: ptr as *mut u8,
|
ptr: ptr as usize,
|
||||||
len: mapping_size,
|
len: mapping_size,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -98,7 +100,7 @@ impl Mmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
ptr: ptr as *mut u8,
|
ptr: ptr as usize,
|
||||||
len: mapping_size,
|
len: mapping_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -142,7 +144,7 @@ impl Mmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
ptr: ptr as *mut u8,
|
ptr: ptr as usize,
|
||||||
len: mapping_size,
|
len: mapping_size,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -154,7 +156,7 @@ impl Mmap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut result = Self {
|
let mut result = Self {
|
||||||
ptr: ptr as *mut u8,
|
ptr: ptr as usize,
|
||||||
len: mapping_size,
|
len: mapping_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -179,7 +181,8 @@ impl Mmap {
|
|||||||
assert_lt!(start, self.len - len);
|
assert_lt!(start, self.len - len);
|
||||||
|
|
||||||
// Commit the accessible size.
|
// Commit the accessible size.
|
||||||
unsafe { region::protect(self.ptr.add(start), len, region::Protection::ReadWrite) }
|
let ptr = self.ptr as *const u8;
|
||||||
|
unsafe { region::protect(ptr.add(start), len, region::Protection::ReadWrite) }
|
||||||
.map_err(|e| e.to_string())
|
.map_err(|e| e.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -198,9 +201,10 @@ impl Mmap {
|
|||||||
assert_lt!(start, self.len - len);
|
assert_lt!(start, self.len - len);
|
||||||
|
|
||||||
// Commit the accessible size.
|
// Commit the accessible size.
|
||||||
|
let ptr = self.ptr as *const u8;
|
||||||
if unsafe {
|
if unsafe {
|
||||||
VirtualAlloc(
|
VirtualAlloc(
|
||||||
self.ptr.add(start) as *mut c_void,
|
ptr.add(start) as *mut c_void,
|
||||||
len,
|
len,
|
||||||
MEM_COMMIT,
|
MEM_COMMIT,
|
||||||
PAGE_READWRITE,
|
PAGE_READWRITE,
|
||||||
@@ -216,22 +220,22 @@ impl Mmap {
|
|||||||
|
|
||||||
/// Return the allocated memory as a slice of u8.
|
/// Return the allocated memory as a slice of u8.
|
||||||
pub fn as_slice(&self) -> &[u8] {
|
pub fn as_slice(&self) -> &[u8] {
|
||||||
unsafe { slice::from_raw_parts(self.ptr, self.len) }
|
unsafe { slice::from_raw_parts(self.ptr as *const u8, self.len) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the allocated memory as a mutable slice of u8.
|
/// Return the allocated memory as a mutable slice of u8.
|
||||||
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
pub fn as_mut_slice(&mut self) -> &mut [u8] {
|
||||||
unsafe { slice::from_raw_parts_mut(self.ptr, self.len) }
|
unsafe { slice::from_raw_parts_mut(self.ptr as *mut u8, self.len) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the allocated memory as a pointer to u8.
|
/// Return the allocated memory as a pointer to u8.
|
||||||
pub fn as_ptr(&self) -> *const u8 {
|
pub fn as_ptr(&self) -> *const u8 {
|
||||||
self.ptr
|
self.ptr as *const u8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the allocated memory as a mutable pointer to u8.
|
/// Return the allocated memory as a mutable pointer to u8.
|
||||||
pub fn as_mut_ptr(&mut self) -> *mut u8 {
|
pub fn as_mut_ptr(&mut self) -> *mut u8 {
|
||||||
self.ptr
|
self.ptr as *mut u8
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the length of the allocated memory.
|
/// Return the length of the allocated memory.
|
||||||
@@ -266,6 +270,11 @@ impl Drop for Mmap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn _assert() {
|
||||||
|
fn _assert_send_sync<T: Send + Sync>() {}
|
||||||
|
_assert_send_sync::<Mmap>();
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
Reference in New Issue
Block a user