core/stdarch/crates/core_arch/src/wasm32/atomic.rs
1#[cfg(test)]
2use stdarch_test::assert_instr;
3
4unsafe extern "unadjusted" {
5 #[link_name = "llvm.wasm.memory.atomic.wait32"]
6 fn llvm_atomic_wait_i32(ptr: *mut i32, exp: i32, timeout: i64) -> i32;
7 #[link_name = "llvm.wasm.memory.atomic.wait64"]
8 fn llvm_atomic_wait_i64(ptr: *mut i64, exp: i64, timeout: i64) -> i32;
9 #[link_name = "llvm.wasm.memory.atomic.notify"]
10 fn llvm_atomic_notify(ptr: *mut i32, cnt: i32) -> i32;
11}
12
13/// Corresponding intrinsic to wasm's [`memory.atomic.wait32` instruction][instr]
14///
15/// This function, when called, will block the current thread if the memory
16/// pointed to by `ptr` is equal to `expression` (performing this action
17/// atomically).
18///
19/// The argument `timeout_ns` is a maximum number of nanoseconds the calling
20/// thread will be blocked for, if it blocks. If the timeout is negative then
21/// the calling thread will be blocked forever.
22///
23/// The calling thread can only be woken up with a call to the `wake` intrinsic
24/// once it has been blocked. Changing the memory behind `ptr` will not wake
25/// the thread once it's blocked.
26///
27/// # Return value
28///
29/// * 0 - indicates that the thread blocked and then was woken up
30/// * 1 - the loaded value from `ptr` didn't match `expression`, the thread
31/// didn't block
32/// * 2 - the thread blocked, but the timeout expired.
33///
34/// [instr]: https://webassembly.github.io/threads/core/syntax/instructions.html#syntax-instr-atomic-memory
35#[inline]
36#[cfg_attr(test, assert_instr(memory.atomic.wait32))]
37#[target_feature(enable = "atomics")]
38#[doc(alias("memory.atomic.wait32"))]
39#[unstable(feature = "stdarch_wasm_atomic_wait", issue = "77839")]
40pub unsafe fn memory_atomic_wait32(ptr: *mut i32, expression: i32, timeout_ns: i64) -> i32 {
41 llvm_atomic_wait_i32(ptr, expression, timeout_ns)
42}
43
44/// Corresponding intrinsic to wasm's [`memory.atomic.wait64` instruction][instr]
45///
46/// This function, when called, will block the current thread if the memory
47/// pointed to by `ptr` is equal to `expression` (performing this action
48/// atomically).
49///
50/// The argument `timeout_ns` is a maximum number of nanoseconds the calling
51/// thread will be blocked for, if it blocks. If the timeout is negative then
52/// the calling thread will be blocked forever.
53///
54/// The calling thread can only be woken up with a call to the `wake` intrinsic
55/// once it has been blocked. Changing the memory behind `ptr` will not wake
56/// the thread once it's blocked.
57///
58/// # Return value
59///
60/// * 0 - indicates that the thread blocked and then was woken up
61/// * 1 - the loaded value from `ptr` didn't match `expression`, the thread
62/// didn't block
63/// * 2 - the thread blocked, but the timeout expired.
64///
65/// [instr]: https://webassembly.github.io/threads/core/syntax/instructions.html#syntax-instr-atomic-memory
66#[inline]
67#[cfg_attr(test, assert_instr(memory.atomic.wait64))]
68#[target_feature(enable = "atomics")]
69#[doc(alias("memory.atomic.wait64"))]
70#[unstable(feature = "stdarch_wasm_atomic_wait", issue = "77839")]
71pub unsafe fn memory_atomic_wait64(ptr: *mut i64, expression: i64, timeout_ns: i64) -> i32 {
72 llvm_atomic_wait_i64(ptr, expression, timeout_ns)
73}
74
75/// Corresponding intrinsic to wasm's [`memory.atomic.notify` instruction][instr]
76///
77/// This function will notify a number of threads blocked on the address
78/// indicated by `ptr`. Threads previously blocked with the `i32_atomic_wait`
79/// and `i64_atomic_wait` functions above will be woken up.
80///
81/// The `waiters` argument indicates how many waiters should be woken up (a
82/// maximum). If the value is zero no waiters are woken up.
83///
84/// # Return value
85///
86/// Returns the number of waiters which were actually notified.
87///
88/// [instr]: https://webassembly.github.io/threads/core/syntax/instructions.html#syntax-instr-atomic-memory
89#[inline]
90#[cfg_attr(test, assert_instr(memory.atomic.notify))]
91#[target_feature(enable = "atomics")]
92#[doc(alias("memory.atomic.notify"))]
93#[unstable(feature = "stdarch_wasm_atomic_wait", issue = "77839")]
94pub unsafe fn memory_atomic_notify(ptr: *mut i32, waiters: u32) -> u32 {
95 llvm_atomic_notify(ptr, waiters as i32) as u32
96}