about summary refs log tree commit diff
diff options
context:
space:
mode:
authorIvan Tham <pickfire@riseup.net>2020-08-30 10:35:50 +0800
committerIvan Tham <pickfire@riseup.net>2020-11-06 23:41:55 +0800
commite8b5be5dffef9ef6a15a085e4b06c4a0471f360d (patch)
tree2bc1c88459052ce4effb6fbb1126d7cc2b006154
parent9f6c670c4b4273b2c7c0af07a524d4240c926bfc (diff)
downloadrust-e8b5be5dffef9ef6a15a085e4b06c4a0471f360d.tar.gz
rust-e8b5be5dffef9ef6a15a085e4b06c4a0471f360d.zip
Stabilize hint::spin_loop
Partially fix #55002, deprecate in another release

Co-authored-by: Ashley Mannix <kodraus@hey.com>

Update stable version for stabilize_spin_loop

Co-authored-by: Joshua Nelson <joshua@yottadb.com>

Use better example for spinlock

As suggested by KodrAus

Remove renamed_spin_loop already available in master

Fix spin loop example
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/core/src/hint.rs62
-rw-r--r--library/core/src/sync/atomic.rs16
-rw-r--r--library/std/src/lib.rs1
4 files changed, 56 insertions, 24 deletions
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 0fe15958076..ccabc336acc 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -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)]
diff --git a/library/core/src/hint.rs b/library/core/src/hint.rs
index 454fb34e77e..979a5f8cf50 100644
--- a/library/core/src/hint.rs
+++ b/library/core/src/hint.rs
@@ -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 @@ use crate::intrinsics;
 /// Otherwise, consider using the [`unreachable!`] macro, which does not allow
 /// optimizations but will panic when executed.
 ///
-///
 /// # Example
 ///
 /// ```
@@ -51,18 +51,62 @@ pub const unsafe fn unreachable_unchecked() -> ! {
     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").
+///
+/// Upon receiving the spin-loop signal the processor can optimize its behavior by,
+/// for example, saving power or switching hyper-threads.
+///
+/// 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.
+///
+/// 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
 ///
-/// For a discussion of different locking strategies and their trade-offs, see
-/// [`core::sync::atomic::spin_loop_hint`].
+/// ```
+/// 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);
+///     })
+/// };
 ///
-/// **Note**: On platforms that do not support receiving spin-loop hints this function does not
-/// do anything at all.
+/// // 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>>(())
+/// ```
 ///
-/// [`core::sync::atomic::spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
+/// [`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"))]
     {
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 5c9cfe27101..5dbea6e71aa 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -115,23 +115,13 @@ use crate::hint::spin_loop;
 
 /// 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() {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 96a7755c688..1636fe5e257 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -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)]