Skip to content

Commit e8b5be5

Browse files
committed
Stabilize hint::spin_loop
Partially fix #55002, deprecate in another release Co-authored-by: Ashley Mannix <[email protected]> Update stable version for stabilize_spin_loop Co-authored-by: Joshua Nelson <[email protected]> Use better example for spinlock As suggested by KodrAus Remove renamed_spin_loop already available in master Fix spin loop example
1 parent 9f6c670 commit e8b5be5

File tree

4 files changed

+56
-24
lines changed

4 files changed

+56
-24
lines changed

library/alloc/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,6 @@
119119
#![feature(raw_ref_op)]
120120
#![feature(rustc_attrs)]
121121
#![feature(receiver_trait)]
122-
#![feature(renamed_spin_loop)]
123122
#![feature(min_specialization)]
124123
#![feature(slice_ptr_get)]
125124
#![feature(slice_ptr_len)]

library/core/src/hint.rs

+53-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#![stable(feature = "core_hint", since = "1.27.0")]
22

33
//! Hints to compiler that affects how code should be emitted or optimized.
4+
//! Hints may be compile time or runtime.
45
56
use crate::intrinsics;
67

@@ -24,7 +25,6 @@ use crate::intrinsics;
2425
/// Otherwise, consider using the [`unreachable!`] macro, which does not allow
2526
/// optimizations but will panic when executed.
2627
///
27-
///
2828
/// # Example
2929
///
3030
/// ```
@@ -51,18 +51,62 @@ pub const unsafe fn unreachable_unchecked() -> ! {
5151
unsafe { intrinsics::unreachable() }
5252
}
5353

54-
/// Emits a machine instruction hinting to the processor that it is running in busy-wait
55-
/// spin-loop ("spin lock").
54+
/// Emits a machine instruction to signal the processor that it is running in
55+
/// a busy-wait spin-loop ("spin lock").
56+
///
57+
/// Upon receiving the spin-loop signal the processor can optimize its behavior by,
58+
/// for example, saving power or switching hyper-threads.
59+
///
60+
/// This function is different from [`thread::yield_now`] which directly
61+
/// yields to the system's scheduler, whereas `spin_loop` does not interact
62+
/// with the operating system.
63+
///
64+
/// A common use case for `spin_loop` is implementing bounded optimistic
65+
/// spinning in a CAS loop in synchronization primitives. To avoid problems
66+
/// like priority inversion, it is strongly recommended that the spin loop is
67+
/// terminated after a finite amount of iterations and an appropriate blocking
68+
/// syscall is made.
69+
///
70+
/// **Note**: On platforms that do not support receiving spin-loop hints this
71+
/// function does not do anything at all.
72+
///
73+
/// # Examples
5674
///
57-
/// For a discussion of different locking strategies and their trade-offs, see
58-
/// [`core::sync::atomic::spin_loop_hint`].
75+
/// ```
76+
/// use std::sync::atomic::{AtomicBool, Ordering};
77+
/// use std::sync::Arc;
78+
/// use std::{hint, thread};
79+
///
80+
/// // A shared atomic value that threads will use to coordinate
81+
/// let live = Arc::new(AtomicBool::new(false));
82+
///
83+
/// // In a background thread we'll eventually set the value
84+
/// let bg_work = {
85+
/// let live = live.clone();
86+
/// thread::spawn(move || {
87+
/// // Do some work, then make the value live
88+
/// do_some_work();
89+
/// live.store(true, Ordering::Release);
90+
/// })
91+
/// };
5992
///
60-
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
61-
/// do anything at all.
93+
/// // Back on our current thread, we wait for the value to be set
94+
/// while live.load(Ordering::Acquire) {
95+
/// // The spin loop is a hint to the CPU that we're waiting, but probably
96+
/// // not for very long
97+
/// hint::spin_loop();
98+
/// }
99+
///
100+
/// // The value is now set
101+
/// # fn do_some_work() {}
102+
/// do_some_work();
103+
/// bg_work.join()?;
104+
/// # Ok::<(), Box<dyn core::any::Any + Send + 'static>>(())
105+
/// ```
62106
///
63-
/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
107+
/// [`thread::yield_now`]: ../../std/thread/fn.yield_now.html
64108
#[inline]
65-
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
109+
#[stable(feature = "renamed_spin_loop", since = "1.49.0")]
66110
pub fn spin_loop() {
67111
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))]
68112
{

library/core/src/sync/atomic.rs

+3-13
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,13 @@ use crate::hint::spin_loop;
115115

116116
/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
117117
///
118-
/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
119-
/// power or switching hyper-threads.
120-
///
121-
/// This function is different from [`std::thread::yield_now`] which directly yields to the
122-
/// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system.
123-
///
124-
/// A common use case for `spin_loop_hint` is implementing bounded optimistic spinning in a CAS
125-
/// loop in synchronization primitives. To avoid problems like priority inversion, it is strongly
126-
/// recommended that the spin loop is terminated after a finite amount of iterations and an
127-
/// appropriate blocking syscall is made.
118+
/// This function is expected to be deprecated in favor of
119+
/// [`hint::spin_loop`].
128120
///
129121
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
130122
/// do anything at all.
131123
///
132-
/// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html
133-
/// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html
134-
/// [`std::sync::Mutex`]: ../../../std/sync/struct.Mutex.html
124+
/// [`hint::spin_loop`]: crate::hint::spin_loop
135125
#[inline]
136126
#[stable(feature = "spin_loop_hint", since = "1.24.0")]
137127
pub fn spin_loop_hint() {

library/std/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,6 @@
296296
#![feature(raw)]
297297
#![feature(raw_ref_macros)]
298298
#![feature(ready_macro)]
299-
#![feature(renamed_spin_loop)]
300299
#![feature(rustc_attrs)]
301300
#![feature(rustc_private)]
302301
#![feature(shrink_to)]

0 commit comments

Comments
 (0)