Skip to content

Commit c8bfaf9

Browse files
committed
Unconditionally expose wasm atomic intrinsics
While they're not very useful in single-threaded mode this makes them more useful for building libraries because you don't have to always recompile the standard library to get the desired effect. Additionally it helps us enable tests on CI for these functions, since the instructions will now validate without shared memory (thankfully!).
1 parent d8aba28 commit c8bfaf9

File tree

4 files changed

+42
-55
lines changed

4 files changed

+42
-55
lines changed

ci/docker/wasm32-wasi/Dockerfile

+1
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,6 @@ COPY --from=0 /usr/local/cargo/bin/wasmtime /usr/local/bin/wasmtime
2020

2121
ENV CARGO_TARGET_WASM32_WASI_RUNNER="wasmtime \
2222
--enable-simd \
23+
--enable-threads \
2324
--mapdir .::/checkout/target/wasm32-wasi/release/deps \
2425
--"

crates/core_arch/src/mod.rs

+33-17
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,23 @@ pub mod arch {
5959
/// Platform-specific intrinsics for the `wasm32` platform.
6060
///
6161
/// This module provides intrinsics specific to the WebAssembly
62-
/// architecture. Here you'll find intrinsics necessary for leveraging
63-
/// WebAssembly proposals such as [atomics] and [simd]. These proposals are
64-
/// evolving over time and as such the support here is unstable and requires
65-
/// the nightly channel. As WebAssembly proposals stabilize these functions
66-
/// will also become stable.
62+
/// architecture. Here you'll find intrinsics specific to WebAssembly that
63+
/// aren't otherwise surfaced somewhere in a cross-platform abstraction of
64+
/// `std`, and you'll also find functions for leveraging WebAssembly
65+
/// proposals such as [atomics] and [simd].
66+
///
67+
/// Intrinsics in the `wasm32` module are modeled after the WebAssembly
68+
/// instructions that they represent. All functions are named after the
69+
/// instruction they intend to correspond to, and the arguments/results
70+
/// correspond to the type signature of the instruction itself. Stable
71+
/// WebAssembly instructions are [documented online][instrdoc].
72+
///
73+
/// [instrdoc]: https://webassembly.github.io/spec/core/valid/instructions.html
74+
///
75+
/// If a proposal is not yet stable in WebAssembly itself then the functions
76+
/// within this function may be unstable and require the nightly channel of
77+
/// Rust to use. As the proposal itself stabilizes the intrinsics in this
78+
/// module should stabilize as well.
6779
///
6880
/// [atomics]: https://github.com/webassembly/threads
6981
/// [simd]: https://github.com/webassembly/simd
@@ -74,18 +86,22 @@ pub mod arch {
7486
/// ## Atomics
7587
///
7688
/// The [threads proposal][atomics] for WebAssembly adds a number of
77-
/// instructions for dealing with multithreaded programs. Atomic
78-
/// instructions can all be generated through `std::sync::atomic` types, but
79-
/// some instructions have no equivalent in Rust such as
80-
/// `memory.atomic.notify` so this module will provide these intrinsics.
81-
///
82-
/// At this time, however, these intrinsics are only available **when the
83-
/// standard library itself is compiled with atomics**. Compiling with
84-
/// atomics is not enabled by default and requires passing
85-
/// `-Ctarget-feature=+atomics` to rustc. The standard library shipped via
86-
/// `rustup` is not compiled with atomics. To get access to these intrinsics
87-
/// you'll need to compile the standard library from source with the
88-
/// requisite compiler flags.
89+
/// instructions for dealing with multithreaded programs. Most instructions
90+
/// added in the [atomics] proposal are exposed in Rust through the
91+
/// `std::sync::atomic` module. Some instructions, however, don't have
92+
/// direct equivalents in Rust so they're exposed here instead.
93+
///
94+
/// Note that the instructions added in the [atomics] proposal can work in
95+
/// either a context with a shared wasm memory and without. These intrinsics
96+
/// are always available in the standard library, but you likely won't be
97+
/// able to use them too productively unless you recompile the standard
98+
/// library (and all your code) with `-Ctarget-feature=+atomics`.
99+
///
100+
/// It's also worth pointing out that multi-threaded WebAssembly and its
101+
/// story in Rust is still in a somewhat "early days" phase as of the time
102+
/// of this writing. Pieces should mostly work but it generally requires a
103+
/// good deal of manual setup. At this time it's not as simple as "just call
104+
/// `std::thread::spawn`", but it will hopefully get there one day!
89105
///
90106
/// ## SIMD
91107
///

crates/core_arch/src/wasm32/atomic.rs

+8-36
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,10 @@
1-
//! Intrinsics associated with WebAssembly's upcoming threads proposal.
2-
//!
3-
//! These intrinsics are all unstable because they're not actually stable in
4-
//! WebAssembly itself yet. The signatures may change as [the
5-
//! specification][spec] is updated.
6-
//!
7-
//! [spec]: https://github.com/WebAssembly/threads
8-
9-
#![cfg(any(target_feature = "atomics", doc))]
10-
111
#[cfg(test)]
122
use stdarch_test::assert_instr;
133

144
extern "C" {
15-
#[link_name = "llvm.wasm.memory.atomic.wait.i32"]
5+
#[link_name = "llvm.wasm.memory.atomic.wait32"]
166
fn llvm_atomic_wait_i32(ptr: *mut i32, exp: i32, timeout: i64) -> i32;
17-
#[link_name = "llvm.wasm.memory.atomic.wait.i64"]
7+
#[link_name = "llvm.wasm.memory.atomic.wait64"]
188
fn llvm_atomic_wait_i64(ptr: *mut i64, exp: i64, timeout: i64) -> i32;
199
#[link_name = "llvm.wasm.memory.atomic.notify"]
2010
fn llvm_atomic_notify(ptr: *mut i32, cnt: i32) -> i32;
@@ -41,16 +31,10 @@ extern "C" {
4131
/// didn't block
4232
/// * 2 - the thread blocked, but the timeout expired.
4333
///
44-
/// # Availability
45-
///
46-
/// This intrinsic is only available **when the standard library itself is
47-
/// compiled with the `atomics` target feature**. This version of the standard
48-
/// library is not obtainable via `rustup`, but rather will require the
49-
/// standard library to be compiled from source.
50-
///
5134
/// [instr]: https://webassembly.github.io/threads/syntax/instructions.html#syntax-instr-atomic-memory
5235
#[inline]
53-
#[cfg_attr(test, assert_instr("i32.atomic.wait"))]
36+
#[cfg_attr(test, assert_instr(memory.atomic.wait32))]
37+
#[target_feature(enable = "atomics")]
5438
pub unsafe fn memory_atomic_wait32(ptr: *mut i32, expression: i32, timeout_ns: i64) -> i32 {
5539
llvm_atomic_wait_i32(ptr, expression, timeout_ns)
5640
}
@@ -76,16 +60,10 @@ pub unsafe fn memory_atomic_wait32(ptr: *mut i32, expression: i32, timeout_ns: i
7660
/// didn't block
7761
/// * 2 - the thread blocked, but the timeout expired.
7862
///
79-
/// # Availability
80-
///
81-
/// This intrinsic is only available **when the standard library itself is
82-
/// compiled with the `atomics` target feature**. This version of the standard
83-
/// library is not obtainable via `rustup`, but rather will require the
84-
/// standard library to be compiled from source.
85-
///
8663
/// [instr]: https://webassembly.github.io/threads/syntax/instructions.html#syntax-instr-atomic-memory
8764
#[inline]
88-
#[cfg_attr(test, assert_instr("i64.atomic.wait"))]
65+
#[cfg_attr(test, assert_instr(memory.atomic.wait64))]
66+
#[target_feature(enable = "atomics")]
8967
pub unsafe fn memory_atomic_wait64(ptr: *mut i64, expression: i64, timeout_ns: i64) -> i32 {
9068
llvm_atomic_wait_i64(ptr, expression, timeout_ns)
9169
}
@@ -103,16 +81,10 @@ pub unsafe fn memory_atomic_wait64(ptr: *mut i64, expression: i64, timeout_ns: i
10381
///
10482
/// Returns the number of waiters which were actually notified.
10583
///
106-
/// # Availability
107-
///
108-
/// This intrinsic is only available **when the standard library itself is
109-
/// compiled with the `atomics` target feature**. This version of the standard
110-
/// library is not obtainable via `rustup`, but rather will require the
111-
/// standard library to be compiled from source.
112-
///
11384
/// [instr]: https://webassembly.github.io/threads/syntax/instructions.html#syntax-instr-atomic-memory
11485
#[inline]
115-
#[cfg_attr(test, assert_instr("atomic.wake"))]
86+
#[cfg_attr(test, assert_instr(memory.atomic.notify))]
87+
#[target_feature(enable = "atomics")]
11688
pub unsafe fn memory_atomic_notify(ptr: *mut i32, waiters: u32) -> u32 {
11789
llvm_atomic_notify(ptr, waiters as i32) as u32
11890
}

crates/core_arch/src/wasm32/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@
33
#[cfg(test)]
44
use stdarch_test::assert_instr;
55

6-
#[cfg(any(target_feature = "atomics", doc))]
76
mod atomic;
8-
#[cfg(any(target_feature = "atomics", doc))]
97
pub use self::atomic::*;
108

119
mod simd128;

0 commit comments

Comments
 (0)