]> git.proxmox.com Git - rustc.git/blob - src/stdsimd/crates/core_arch/src/wasm32/atomic.rs
New upstream version 1.34.2+dfsg1
[rustc.git] / src / stdsimd / crates / core_arch / src / wasm32 / atomic.rs
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", dox))]
10
11 #[cfg(test)]
12 use stdsimd_test::assert_instr;
13 #[cfg(test)]
14 use wasm_bindgen_test::wasm_bindgen_test;
15
16 extern "C" {
17 #[link_name = "llvm.wasm.atomic.wait.i32"]
18 fn llvm_atomic_wait_i32(ptr: *mut i32, exp: i32, timeout: i64) -> i32;
19 #[link_name = "llvm.wasm.atomic.wait.i64"]
20 fn llvm_atomic_wait_i64(ptr: *mut i64, exp: i64, timeout: i64) -> i32;
21 #[link_name = "llvm.wasm.atomic.notify"]
22 fn llvm_atomic_notify(ptr: *mut i32, cnt: i32) -> i32;
23 }
24
25 /// Corresponding intrinsic to wasm's [`i32.atomic.wait` instruction][instr]
26 ///
27 /// This function, when called, will block the current thread if the memory
28 /// pointed to by `ptr` is equal to `expression` (performing this action
29 /// atomically).
30 ///
31 /// The argument `timeout_ns` is a maxinum number of nanoseconds the calling
32 /// thread will be blocked for, if it blocks. If the timeout is negative then
33 /// the calling thread will be blocked forever.
34 ///
35 /// The calling thread can only be woken up with a call to the `wake` intrinsic
36 /// once it has been blocked. Changing the memory behind `ptr` will not wake
37 /// the thread once it's blocked.
38 ///
39 /// # Return value
40 ///
41 /// * 0 - indicates that the thread blocked and then was woken up
42 /// * 1 - the loaded value from `ptr` didn't match `expression`, the thread
43 /// didn't block
44 /// * 2 - the thread blocked, but the timeout expired.
45 ///
46 /// # Availability
47 ///
48 /// This intrinsic is only available **when the standard library itself is
49 /// compiled with the `atomics` target feature**. This version of the standard
50 /// library is not obtainable via `rustup`, but rather will require the
51 /// standard library to be compiled from source.
52 ///
53 /// [instr]: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#wait
54 #[inline]
55 #[cfg_attr(test, assert_instr("i32.atomic.wait"))]
56 pub unsafe fn i32_atomic_wait(ptr: *mut i32, expression: i32, timeout_ns: i64) -> i32 {
57 llvm_atomic_wait_i32(ptr, expression, timeout_ns)
58 }
59
60 /// Corresponding intrinsic to wasm's [`i64.atomic.wait` instruction][instr]
61 ///
62 /// This function, when called, will block the current thread if the memory
63 /// pointed to by `ptr` is equal to `expression` (performing this action
64 /// atomically).
65 ///
66 /// The argument `timeout_ns` is a maxinum number of nanoseconds the calling
67 /// thread will be blocked for, if it blocks. If the timeout is negative then
68 /// the calling thread will be blocked forever.
69 ///
70 /// The calling thread can only be woken up with a call to the `wake` intrinsic
71 /// once it has been blocked. Changing the memory behind `ptr` will not wake
72 /// the thread once it's blocked.
73 ///
74 /// # Return value
75 ///
76 /// * 0 - indicates that the thread blocked and then was woken up
77 /// * 1 - the loaded value from `ptr` didn't match `expression`, the thread
78 /// didn't block
79 /// * 2 - the thread blocked, but the timeout expired.
80 ///
81 /// # Availability
82 ///
83 /// This intrinsic is only available **when the standard library itself is
84 /// compiled with the `atomics` target feature**. This version of the standard
85 /// library is not obtainable via `rustup`, but rather will require the
86 /// standard library to be compiled from source.
87 ///
88 /// [instr]: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#wait
89 #[inline]
90 #[cfg_attr(test, assert_instr("i64.atomic.wait"))]
91 pub unsafe fn i64_atomic_wait(ptr: *mut i64, expression: i64, timeout_ns: i64) -> i32 {
92 llvm_atomic_wait_i64(ptr, expression, timeout_ns)
93 }
94
95 /// Corresponding intrinsic to wasm's [`atomic.notify` instruction][instr]
96 ///
97 /// This function will notify a number of threads blocked on the address
98 /// indicated by `ptr`. Threads previously blocked with the `i32_atomic_wait`
99 /// and `i64_atomic_wait` functions above will be woken up.
100 ///
101 /// The `waiters` argument indicates how many waiters should be woken up (a
102 /// maximum). If the value is zero no waiters are woken up.
103 ///
104 /// # Return value
105 ///
106 /// Returns the number of waiters which were actually notified.
107 ///
108 /// # Availability
109 ///
110 /// This intrinsic is only available **when the standard library itself is
111 /// compiled with the `atomics` target feature**. This version of the standard
112 /// library is not obtainable via `rustup`, but rather will require the
113 /// standard library to be compiled from source.
114 ///
115 /// [instr]: https://github.com/WebAssembly/threads/blob/master/proposals/threads/Overview.md#wake
116 #[inline]
117 #[cfg_attr(test, assert_instr("atomic.wake"))]
118 pub unsafe fn atomic_notify(ptr: *mut i32, waiters: u32) -> u32 {
119 llvm_atomic_notify(ptr, waiters as i32) as u32
120 }