Rollup merge of #76097 - pickfire:stabilize-spin-loop, r=KodrAus
Stabilize hint::spin_loop Partially fix #55002, deprecate in another release r? ``````@KodrAus``````
This commit is contained in:
commit
1f034f77bc
@ -119,7 +119,6 @@
|
||||
#![feature(raw_ref_op)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(receiver_trait)]
|
||||
#![feature(renamed_spin_loop)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(slice_ptr_get)]
|
||||
#![feature(slice_ptr_len)]
|
||||
|
@ -1,6 +1,7 @@
|
||||
#![stable(feature = "core_hint", since = "1.27.0")]
|
||||
|
||||
//! Hints to compiler that affects how code should be emitted or optimized.
|
||||
//! Hints may be compile time or runtime.
|
||||
|
||||
use crate::intrinsics;
|
||||
|
||||
@ -24,7 +25,6 @@
|
||||
/// Otherwise, consider using the [`unreachable!`] macro, which does not allow
|
||||
/// optimizations but will panic when executed.
|
||||
///
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
@ -51,18 +51,62 @@
|
||||
unsafe { intrinsics::unreachable() }
|
||||
}
|
||||
|
||||
/// Emits a machine instruction hinting to the processor that it is running in busy-wait
|
||||
/// spin-loop ("spin lock").
|
||||
/// Emits a machine instruction to signal the processor that it is running in
|
||||
/// a busy-wait spin-loop ("spin lock").
|
||||
///
|
||||
/// For a discussion of different locking strategies and their trade-offs, see
|
||||
/// [`core::sync::atomic::spin_loop_hint`].
|
||||
/// Upon receiving the spin-loop signal the processor can optimize its behavior by,
|
||||
/// for example, saving power or switching hyper-threads.
|
||||
///
|
||||
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
|
||||
/// do anything at all.
|
||||
/// This function is different from [`thread::yield_now`] which directly
|
||||
/// yields to the system's scheduler, whereas `spin_loop` does not interact
|
||||
/// with the operating system.
|
||||
///
|
||||
/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
|
||||
/// A common use case for `spin_loop` is implementing bounded optimistic
|
||||
/// spinning in a CAS loop in synchronization primitives. To avoid problems
|
||||
/// like priority inversion, it is strongly recommended that the spin loop is
|
||||
/// terminated after a finite amount of iterations and an appropriate blocking
|
||||
/// syscall is made.
|
||||
///
|
||||
/// **Note**: On platforms that do not support receiving spin-loop hints this
|
||||
/// function does not do anything at all.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::sync::atomic::{AtomicBool, Ordering};
|
||||
/// use std::sync::Arc;
|
||||
/// use std::{hint, thread};
|
||||
///
|
||||
/// // A shared atomic value that threads will use to coordinate
|
||||
/// let live = Arc::new(AtomicBool::new(false));
|
||||
///
|
||||
/// // In a background thread we'll eventually set the value
|
||||
/// let bg_work = {
|
||||
/// let live = live.clone();
|
||||
/// thread::spawn(move || {
|
||||
/// // Do some work, then make the value live
|
||||
/// do_some_work();
|
||||
/// live.store(true, Ordering::Release);
|
||||
/// })
|
||||
/// };
|
||||
///
|
||||
/// // Back on our current thread, we wait for the value to be set
|
||||
/// while live.load(Ordering::Acquire) {
|
||||
/// // The spin loop is a hint to the CPU that we're waiting, but probably
|
||||
/// // not for very long
|
||||
/// hint::spin_loop();
|
||||
/// }
|
||||
///
|
||||
/// // The value is now set
|
||||
/// # fn do_some_work() {}
|
||||
/// do_some_work();
|
||||
/// bg_work.join()?;
|
||||
/// # Ok::<(), Box<dyn core::any::Any + Send + 'static>>(())
|
||||
/// ```
|
||||
///
|
||||
/// [`thread::yield_now`]: ../../std/thread/fn.yield_now.html
|
||||
#[inline]
|
||||
#[unstable(feature = "renamed_spin_loop", issue = "55002")]
|
||||
#[stable(feature = "renamed_spin_loop", since = "1.49.0")]
|
||||
pub fn spin_loop() {
|
||||
#[cfg(all(any(target_arch = "x86", target_arch = "x86_64"), target_feature = "sse2"))]
|
||||
{
|
||||
|
@ -115,23 +115,13 @@
|
||||
|
||||
/// Signals the processor that it is inside a busy-wait spin-loop ("spin lock").
|
||||
///
|
||||
/// Upon receiving spin-loop signal the processor can optimize its behavior by, for example, saving
|
||||
/// power or switching hyper-threads.
|
||||
///
|
||||
/// This function is different from [`std::thread::yield_now`] which directly yields to the
|
||||
/// system's scheduler, whereas `spin_loop_hint` does not interact with the operating system.
|
||||
///
|
||||
/// A common use case for `spin_loop_hint` is implementing bounded optimistic spinning in a CAS
|
||||
/// loop in synchronization primitives. To avoid problems like priority inversion, it is strongly
|
||||
/// recommended that the spin loop is terminated after a finite amount of iterations and an
|
||||
/// appropriate blocking syscall is made.
|
||||
/// This function is expected to be deprecated in favor of
|
||||
/// [`hint::spin_loop`].
|
||||
///
|
||||
/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
|
||||
/// do anything at all.
|
||||
///
|
||||
/// [`std::thread::yield_now`]: ../../../std/thread/fn.yield_now.html
|
||||
/// [`std::thread::sleep`]: ../../../std/thread/fn.sleep.html
|
||||
/// [`std::sync::Mutex`]: ../../../std/sync/struct.Mutex.html
|
||||
/// [`hint::spin_loop`]: crate::hint::spin_loop
|
||||
#[inline]
|
||||
#[stable(feature = "spin_loop_hint", since = "1.24.0")]
|
||||
pub fn spin_loop_hint() {
|
||||
|
@ -296,7 +296,6 @@
|
||||
#![feature(raw)]
|
||||
#![feature(raw_ref_macros)]
|
||||
#![feature(ready_macro)]
|
||||
#![feature(renamed_spin_loop)]
|
||||
#![feature(rustc_attrs)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(shrink_to)]
|
||||
|
Loading…
Reference in New Issue
Block a user