Skip to content

Commit

Permalink
Document what effect hints have on loom (#358)
Browse files Browse the repository at this point in the history
Co-authored-by: Motoyuki Kimura <[email protected]>
  • Loading branch information
udoprog and mox692 authored Dec 8, 2024
1 parent b810b4a commit 3ef62e2
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 0 deletions.
6 changes: 6 additions & 0 deletions src/hint.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
//! Mocked versions of [`std::hint`] functions.
/// Signals the processor that it is entering a busy-wait spin-loop.
///
/// For loom, this is an alias of [`yield_now`] but is provided as a reflection
/// of the [`core::hint::spin_loop`] function. See the [`yield_now`]
/// documentation for more information on what effect this has.
///
/// [`yield_now`]: crate::thread::yield_now
pub fn spin_loop() {
crate::sync::atomic::spin_loop_hint();
}
Expand Down
89 changes: 89 additions & 0 deletions src/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,95 @@ where
///
/// This enables concurrent algorithms that require other threads to make
/// progress.
///
/// Using this as a hint might be necessary to reduce the number of branches
/// being investigated by loom. This might be necessary when testing spin locks,
/// since each iteration constitutes a branch point which might easily cause a
/// combinatorial explosion.
///
/// Note that in loom, [`spin_loop`] and [`spin_loop_hint`] is an alias of this
/// function.
///
/// [`spin_loop`]: crate::hint::spin_loop
/// [`spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
///
/// # Examples
///
/// Testing a raw spin lock under loom.
///
/// This is only provided as an example for when using [`spin_loop`] and
/// [`yield_now`] could be appropriate. Using a spin lock is almost always worse
/// than using a [`Mutex`] directly which spins internally before parking the
/// thread if contention is detected to save on system resources.
///
/// [`Mutex`]: std::sync::Mutex
/// [`spin_loop_hint`]: crate::sync::atomic::spin_loop_hint
/// [`spin_loop`]: crate::hint::spin_loop
///
/// ```no_run
/// use loom::sync::atomic::AtomicBool;
/// use loom::hint;
/// use loom::thread;
///
/// use std::sync::Arc;
/// use std::sync::atomic::Ordering::{Acquire, Relaxed, SeqCst};
///
/// struct Lock {
/// locked: AtomicBool,
/// }
///
/// impl Lock {
/// fn new() -> Self {
/// Lock {
/// locked: AtomicBool::new(false),
/// }
/// }
///
/// fn spin(&self) {
/// while self.locked.load(Relaxed) {
/// hint::spin_loop();
/// }
/// }
///
/// fn lock(&self) {
/// loop {
/// self.spin();
///
/// if self.locked.compare_exchange(false, true, Acquire, Relaxed).is_ok() {
/// break;
/// }
///
/// thread::yield_now();
/// }
/// }
///
/// fn unlock(&self) {
/// self.locked.store(false, SeqCst);
/// }
/// }
///
/// # /*
/// #[test]
/// # */
/// fn test_concurrent_logic() {
/// loom::model(|| {
/// let v1 = Arc::new(Lock::new());
/// let v2 = v1.clone();
///
/// let t1 = thread::spawn(move || {
/// v2.lock();
/// // critical section.
/// v2.unlock();
/// });
///
/// v1.lock();
/// // critical section.
/// v1.unlock();
///
/// t1.join().unwrap();
/// });
/// }
/// ```
pub fn yield_now() {
let switch = execution(|execution| {
let thread = execution.threads.active_id();
Expand Down
7 changes: 7 additions & 0 deletions src/sync/atomic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ pub use self::ptr::AtomicPtr;
pub use std::sync::atomic::Ordering;

/// Signals the processor that it is entering a busy-wait spin-loop.
///
/// For loom, this is an alias of [`yield_now`] but is provided as a reflection
/// of the deprecated [`core::sync::atomic::spin_loop_hint`] function. See the
/// [`yield_now`] documentation for more information on what effect using this
/// has on loom.
///
/// [`yield_now`]: crate::thread::yield_now
pub fn spin_loop_hint() {
crate::thread::yield_now();
}
Expand Down

0 comments on commit 3ef62e2

Please sign in to comment.