mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-07 13:18:20 +00:00
Fix Wait/Notify opcode, the waiters hashmap is now on the Memory itself (#3723)
* Fix Wait/Notify opcode, the waiters hashmap is now on the Memory itself * Refactored for clarity * Use WAIT_ERROR everywhere * Change from WAIT_ERROR to Option * Added some unit test for threadconditions * Switch from `Mutex<HashMap<...>>` to `DashMap<...>` for the NotifyMap * Use FnvHasher for Dashmap * Change timeout value in unit test to leave more margin to the system to react. * Consolidate code, avoid duplication * Put test in a test module * Use an Result with custom error instead of an option for waiter
This commit is contained in:
@@ -5,6 +5,8 @@
|
||||
//!
|
||||
//! `Memory` is to WebAssembly linear memories what `Table` is to WebAssembly tables.
|
||||
|
||||
use crate::threadconditions::ThreadConditions;
|
||||
pub use crate::threadconditions::{NotifyLocation, WaiterError};
|
||||
use crate::trap::Trap;
|
||||
use crate::{mmap::Mmap, store::MaybeInstanceOwned, vmcontext::VMMemoryDefinition};
|
||||
use more_asserts::assert_ge;
|
||||
@@ -13,6 +15,7 @@ use std::convert::TryInto;
|
||||
use std::ptr::NonNull;
|
||||
use std::slice;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use std::time::Duration;
|
||||
use wasmer_types::{Bytes, MemoryError, MemoryStyle, MemoryType, Pages};
|
||||
|
||||
// The memory mapped area
|
||||
@@ -285,6 +288,7 @@ impl VMOwnedMemory {
|
||||
VMSharedMemory {
|
||||
mmap: Arc::new(RwLock::new(self.mmap)),
|
||||
config: self.config,
|
||||
conditions: ThreadConditions::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,6 +350,8 @@ pub struct VMSharedMemory {
|
||||
mmap: Arc<RwLock<WasmMmap>>,
|
||||
// Configuration of this memory
|
||||
config: VMMemoryConfig,
|
||||
// waiters list for this memory
|
||||
conditions: ThreadConditions,
|
||||
}
|
||||
|
||||
unsafe impl Send for VMSharedMemory {}
|
||||
@@ -381,6 +387,7 @@ impl VMSharedMemory {
|
||||
Ok(Self {
|
||||
mmap: Arc::new(RwLock::new(guard.duplicate()?)),
|
||||
config: self.config.clone(),
|
||||
conditions: ThreadConditions::new(),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -431,6 +438,20 @@ impl LinearMemory for VMSharedMemory {
|
||||
let forked = Self::duplicate(self)?;
|
||||
Ok(Box::new(forked))
|
||||
}
|
||||
|
||||
// Add current thread to waiter list
|
||||
fn do_wait(
|
||||
&mut self,
|
||||
dst: NotifyLocation,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<u32, WaiterError> {
|
||||
self.conditions.do_wait(dst, timeout)
|
||||
}
|
||||
|
||||
/// Notify waiters from the wait list. Return the number of waiters notified
|
||||
fn do_notify(&mut self, dst: NotifyLocation, count: u32) -> u32 {
|
||||
self.conditions.do_notify(dst, count)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<VMOwnedMemory> for VMMemory {
|
||||
@@ -498,6 +519,20 @@ impl LinearMemory for VMMemory {
|
||||
fn duplicate(&mut self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError> {
|
||||
self.0.duplicate()
|
||||
}
|
||||
|
||||
// Add current thread to waiter list
|
||||
fn do_wait(
|
||||
&mut self,
|
||||
dst: NotifyLocation,
|
||||
timeout: Option<Duration>,
|
||||
) -> Result<u32, WaiterError> {
|
||||
self.0.do_wait(dst, timeout)
|
||||
}
|
||||
|
||||
/// Notify waiters from the wait list. Return the number of waiters notified
|
||||
fn do_notify(&mut self, dst: NotifyLocation, count: u32) -> u32 {
|
||||
self.0.do_notify(dst, count)
|
||||
}
|
||||
}
|
||||
|
||||
impl VMMemory {
|
||||
@@ -616,4 +651,19 @@ where
|
||||
|
||||
/// Copies this memory to a new memory
|
||||
fn duplicate(&mut self) -> Result<Box<dyn LinearMemory + 'static>, MemoryError>;
|
||||
|
||||
/// Add current thread to the waiter hash, and wait until notified or timout.
|
||||
/// Return 0 if the waiter has been notified, 2 if the timeout occured, or None if en error happened
|
||||
fn do_wait(
|
||||
&mut self,
|
||||
_dst: NotifyLocation,
|
||||
_timeout: Option<Duration>,
|
||||
) -> Result<u32, WaiterError> {
|
||||
Err(WaiterError::Unimplemented)
|
||||
}
|
||||
|
||||
/// Notify waiters from the wait list. Return the number of waiters notified
|
||||
fn do_notify(&mut self, _dst: NotifyLocation, _count: u32) -> u32 {
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user