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
56use  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 " ) ]  
66110pub  fn  spin_loop ( )  { 
67111    #[ cfg( all( any( target_arch = "x86" ,  target_arch = "x86_64" ) ,  target_feature = "sse2" ) ) ]  
68112    { 
0 commit comments