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