mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-06 20:58:28 +00:00
Implemented shared memory for Wasmer in preparation for multithreading
Fixed linter Fixed clippy Cleaned up some merge leftover
This commit is contained in:
committed by
ptitSeb
parent
0928629051
commit
a5f641b4b0
@@ -12,6 +12,7 @@ use std::cell::UnsafeCell;
|
||||
use std::convert::TryInto;
|
||||
use std::ptr::NonNull;
|
||||
use std::slice;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use wasmer_types::{Bytes, MemoryError, MemoryStyle, MemoryType, Pages};
|
||||
|
||||
// The memory mapped area
|
||||
@@ -156,6 +157,18 @@ pub struct VMOwnedMemory {
|
||||
unsafe impl Send for VMOwnedMemory {}
|
||||
unsafe impl Sync for VMOwnedMemory {}
|
||||
|
||||
/// A shared linear memory instance.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct VMSharedMemory {
|
||||
// The underlying allocation.
|
||||
mmap: Arc<RwLock<WasmMmap>>,
|
||||
// Configuration of this memory
|
||||
config: VMMemoryConfig,
|
||||
}
|
||||
|
||||
unsafe impl Send for VMSharedMemory {}
|
||||
unsafe impl Sync for VMSharedMemory {}
|
||||
|
||||
impl VMOwnedMemory {
|
||||
/// Create a new linear memory instance with specified minimum and maximum number of wasm pages.
|
||||
///
|
||||
@@ -259,6 +272,16 @@ impl VMOwnedMemory {
|
||||
}
|
||||
}
|
||||
|
||||
impl VMOwnedMemory {
|
||||
/// Converts this owned memory into shared memory
|
||||
pub fn to_shared(self) -> VMSharedMemory {
|
||||
VMSharedMemory {
|
||||
mmap: Arc::new(RwLock::new(self.mmap)),
|
||||
config: self.config,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl LinearMemory for VMOwnedMemory {
|
||||
/// Returns the type for this memory.
|
||||
fn ty(&self) -> MemoryType {
|
||||
@@ -295,12 +318,85 @@ impl LinearMemory for VMOwnedMemory {
|
||||
}
|
||||
}
|
||||
|
||||
impl VMSharedMemory {
|
||||
/// Create a new linear memory instance with specified minimum and maximum number of wasm pages.
|
||||
///
|
||||
/// This creates a `Memory` with owned metadata: this can be used to create a memory
|
||||
/// that will be imported into Wasm modules.
|
||||
pub fn new(memory: &MemoryType, style: &MemoryStyle) -> Result<Self, MemoryError> {
|
||||
Ok(VMOwnedMemory::new(memory, style)?.to_shared())
|
||||
}
|
||||
|
||||
/// Create a new linear memory instance with specified minimum and maximum number of wasm pages.
|
||||
///
|
||||
/// This creates a `Memory` with metadata owned by a VM, pointed to by
|
||||
/// `vm_memory_location`: this can be used to create a local memory.
|
||||
///
|
||||
/// # Safety
|
||||
/// - `vm_memory_location` must point to a valid location in VM memory.
|
||||
pub unsafe fn from_definition(
|
||||
memory: &MemoryType,
|
||||
style: &MemoryStyle,
|
||||
vm_memory_location: NonNull<VMMemoryDefinition>,
|
||||
) -> Result<Self, MemoryError> {
|
||||
Ok(VMOwnedMemory::from_definition(memory, style, vm_memory_location)?.to_shared())
|
||||
}
|
||||
}
|
||||
|
||||
impl LinearMemory for VMSharedMemory {
|
||||
/// Returns the type for this memory.
|
||||
fn ty(&self) -> MemoryType {
|
||||
let minimum = {
|
||||
let guard = self.mmap.read().unwrap();
|
||||
guard.size()
|
||||
};
|
||||
self.config.ty(minimum)
|
||||
}
|
||||
|
||||
/// Returns the size of hte memory in pages
|
||||
fn size(&self) -> Pages {
|
||||
let guard = self.mmap.read().unwrap();
|
||||
guard.size()
|
||||
}
|
||||
|
||||
/// Returns the memory style for this memory.
|
||||
fn style(&self) -> MemoryStyle {
|
||||
self.config.style()
|
||||
}
|
||||
|
||||
/// Grow memory by the specified amount of wasm pages.
|
||||
///
|
||||
/// Returns `None` if memory can't be grown by the specified amount
|
||||
/// of wasm pages.
|
||||
fn grow(&mut self, delta: Pages) -> Result<Pages, MemoryError> {
|
||||
let mut guard = self.mmap.write().unwrap();
|
||||
guard.grow(delta, self.config.clone())
|
||||
}
|
||||
|
||||
/// Return a `VMMemoryDefinition` for exposing the memory to compiled wasm code.
|
||||
fn vmmemory(&self) -> NonNull<VMMemoryDefinition> {
|
||||
let guard = self.mmap.read().unwrap();
|
||||
guard.vm_memory_definition.as_ptr()
|
||||
}
|
||||
|
||||
/// Owned memory can not be cloned (this will always return None)
|
||||
fn try_clone(&self) -> Option<Box<dyn LinearMemory + 'static>> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VMOwnedMemory> for VMMemory {
|
||||
fn from(mem: VMOwnedMemory) -> Self {
|
||||
Self(Box::new(mem))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VMSharedMemory> for VMMemory {
|
||||
fn from(mem: VMSharedMemory) -> Self {
|
||||
Self(Box::new(mem))
|
||||
}
|
||||
}
|
||||
|
||||
/// Represents linear memory that can be either owned or shared
|
||||
#[derive(Debug)]
|
||||
pub struct VMMemory(pub Box<dyn LinearMemory + 'static>);
|
||||
@@ -357,8 +453,12 @@ impl VMMemory {
|
||||
///
|
||||
/// This creates a `Memory` with owned metadata: this can be used to create a memory
|
||||
/// that will be imported into Wasm modules.
|
||||
pub fn new(memory: &MemoryType, style: &MemoryStyle) -> Result<Self, MemoryError> {
|
||||
Ok(Self(Box::new(VMOwnedMemory::new(memory, style)?)))
|
||||
pub fn new(memory: &MemoryType, style: &MemoryStyle) -> Result<VMMemory, MemoryError> {
|
||||
Ok(if memory.shared {
|
||||
Self(Box::new(VMSharedMemory::new(memory, style)?))
|
||||
} else {
|
||||
Self(Box::new(VMOwnedMemory::new(memory, style)?))
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns the number of pages in the allocated memory block
|
||||
@@ -377,12 +477,20 @@ impl VMMemory {
|
||||
memory: &MemoryType,
|
||||
style: &MemoryStyle,
|
||||
vm_memory_location: NonNull<VMMemoryDefinition>,
|
||||
) -> Result<Self, MemoryError> {
|
||||
Ok(Self(Box::new(VMOwnedMemory::from_definition(
|
||||
memory,
|
||||
style,
|
||||
vm_memory_location,
|
||||
)?)))
|
||||
) -> Result<VMMemory, MemoryError> {
|
||||
Ok(if memory.shared {
|
||||
Self(Box::new(VMSharedMemory::from_definition(
|
||||
memory,
|
||||
style,
|
||||
vm_memory_location,
|
||||
)?))
|
||||
} else {
|
||||
Self(Box::new(VMOwnedMemory::from_definition(
|
||||
memory,
|
||||
style,
|
||||
vm_memory_location,
|
||||
)?))
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates VMMemory from a custom implementation - the following into implementations
|
||||
|
||||
Reference in New Issue
Block a user