wiggle: add initial support for shared memory (#5225)

This change is the first in a series of changes to support shared memory
in Wiggle. Since Wiggle was written under the assumption of
single-threaded guest-side access, this change introduces a `shared`
field to guest memories in order to flag when this assumption will not
be the case. This change always sets `shared` to `false`; once a few
more pieces are in place, `shared` will be set dynamically when a shared
memory is detected, e.g., in a change like #5054.

Using the `shared` field, we can now decide to load Wiggle values
differently under the new assumptions. This change  makes the guest
`T::read` and `T::write` calls into `Relaxed` atomic loads and stores in
order to maintain WebAssembly's expected memory consistency guarantees.
We choose Rust's `Relaxed` here to match the `Unordered` memory
consistency described in the [memory model] section of the ECMA spec.
These relaxed accesses are done unconditionally, since we theorize that
the performance benefit of an additional branch vs a relaxed load is
not much.

[memory model]: https://tc39.es/ecma262/multipage/memory-model.html#sec-memory-model

Since 128-bit scalar types do not have `Atomic*` equivalents, we remove
their `T::read` and `T::write` implementations here. They are unused by
any WASI implementations in the project.
This commit is contained in:
Andrew Brown
2022-11-08 13:25:24 -08:00
committed by GitHub
parent 50cffad0d3
commit f026d95a1a
4 changed files with 123 additions and 16 deletions

View File

@@ -192,6 +192,12 @@ pub unsafe trait GuestMemory: Send + Sync {
/// `GuestStr` are implemented correctly, a shared `BorrowHandle` should only be
/// unborrowed once.
fn shared_unborrow(&self, h: BorrowHandle);
/// Check if the underlying memory is shared across multiple threads; e.g.,
/// with a WebAssembly shared memory.
fn is_shared_memory(&self) -> bool {
false
}
}
/// A handle to a borrow on linear memory. It is produced by `{mut, shared}_borrow` and