File tree Expand file tree Collapse file tree 3 files changed +65
-0
lines changed
Expand file tree Collapse file tree 3 files changed +65
-0
lines changed Original file line number Diff line number Diff line change 145145 - [ future_atomic_orderings] ( library-features/future-atomic-orderings.md )
146146 - [ get_type_id] ( library-features/get-type-id.md )
147147 - [ heap_api] ( library-features/heap-api.md )
148+ - [ hint_core_should_pause] ( library-features/hint-core-should-pause.md )
148149 - [ i128] ( library-features/i128.md )
149150 - [ inclusive_range] ( library-features/inclusive-range.md )
150151 - [ integer_atomics] ( library-features/integer-atomics.md )
Original file line number Diff line number Diff line change 1+ # ` hint_core_should_pause `
2+
3+ The tracking issue for this feature is: [ #41196 ]
4+
5+ [ #41196 ] : https://github.com/rust-lang/rust/issues/41196
6+
7+ ------------------------
8+
9+ Many programs have spin loops like the following:
10+
11+ ``` rust,no_run
12+ use std::sync::atomic::{AtomicBool,Ordering};
13+
14+ fn spin_loop(value: &AtomicBool) {
15+ loop {
16+ if value.load(Ordering::Acquire) {
17+ break;
18+ }
19+ }
20+ }
21+ ```
22+
23+ These programs can be improved in performance like so:
24+
25+ ``` rust,no_run
26+ #![feature(hint_core_should_pause)]
27+ use std::sync::atomic;
28+ use std::sync::atomic::{AtomicBool,Ordering};
29+
30+ fn spin_loop(value: &AtomicBool) {
31+ loop {
32+ if value.load(Ordering::Acquire) {
33+ break;
34+ }
35+ atomic::hint_core_should_pause();
36+ }
37+ }
38+ ```
39+
40+ Further improvements could combine ` hint_core_should_pause ` with
41+ exponential backoff or ` std::thread::yield_now ` .
Original file line number Diff line number Diff line change @@ -94,6 +94,29 @@ use intrinsics;
9494use cell:: UnsafeCell ;
9595use fmt;
9696
97+ /// Save power or switch hyperthreads in a busy-wait spin-loop.
98+ ///
99+ /// This function is deliberately more primitive than
100+ /// `std::thread::yield_now` and does not directly yield to the
101+ /// system's scheduler. In some cases it might be useful to use a
102+ /// combination of both functions. Careful benchmarking is advised.
103+ ///
104+ /// On some platforms this function may not do anything at all.
105+ #[ inline]
106+ #[ unstable( feature = "hint_core_should_pause" , issue = "41196" ) ]
107+ pub fn hint_core_should_pause ( )
108+ {
109+ #[ cfg( any( target_arch = "x86" , target_arch = "x86_64" ) ) ]
110+ unsafe {
111+ asm ! ( "pause" :: : "memory" : "volatile" ) ;
112+ }
113+
114+ #[ cfg( target_arch = "aarch64" ) ]
115+ unsafe {
116+ asm ! ( "yield" :: : "memory" : "volatile" ) ;
117+ }
118+ }
119+
97120/// A boolean type which can be safely shared between threads.
98121///
99122/// This type has the same in-memory representation as a `bool`.
You can’t perform that action at this time.
0 commit comments