Skip to content

Commit

Permalink
document memory orderings of thread::{park, unpark}
Browse files Browse the repository at this point in the history
  • Loading branch information
ibraheemdev committed Jul 22, 2022
1 parent 31b9b01 commit 9de1d7c
Showing 1 changed file with 19 additions and 9 deletions.
28 changes: 19 additions & 9 deletions library/std/src/thread/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -845,7 +845,7 @@ pub fn sleep(dur: Duration) {
/// A call to `park` does not guarantee that the thread will remain parked
/// forever, and callers should be prepared for this possibility.
///
/// # park and unpark
/// # `park` and `unpark`
///
/// Every thread is equipped with some basic low-level blocking support, via the
/// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`unpark`]
Expand All @@ -866,14 +866,6 @@ pub fn sleep(dur: Duration) {
/// if it wasn't already. Because the token is initially absent, [`unpark`]
/// followed by [`park`] will result in the second call returning immediately.
///
/// In other words, each [`Thread`] acts a bit like a spinlock that can be
/// locked and unlocked using `park` and `unpark`.
///
/// Notice that being unblocked does not imply any synchronization with someone
/// that unparked this thread, it could also be spurious.
/// For example, it would be a valid, but inefficient, implementation to make both [`park`] and
/// [`unpark`] return immediately without doing anything.
///
/// The API is typically used by acquiring a handle to the current thread,
/// placing that handle in a shared data structure so that other threads can
/// find it, and then `park`ing in a loop. When some desired condition is met, another
Expand All @@ -887,6 +879,23 @@ pub fn sleep(dur: Duration) {
///
/// * It can be implemented very efficiently on many platforms.
///
/// # Memory Orderings
///
/// Calls to `park` _synchronize-with_ calls to `unpark`, meaning that memory
/// operations performed before a call to `unpark` are made visible to the thread that
/// consumes the token and returns from `park`. Note that all `park` and `unpark`
/// operations for a given thread form a total order and `park` synchronizes-with
/// _all_ prior `unpark` operations.
///
/// In atomic ordering terms, `unpark` performs a `Release` operation and `park`
/// performs the corresponding `Acquire` operation. Calls to `unpark` for the same
/// thread form a [release sequence].
///
/// Notice that being unblocked does not imply any synchronization with someone that
/// unparked this thread, it could also be spurious. For example, it would be a valid,
/// but inefficient, implementation to make both park and unpark return immediately
/// without doing anything.
///
/// # Examples
///
/// ```
Expand Down Expand Up @@ -926,6 +935,7 @@ pub fn sleep(dur: Duration) {
///
/// [`unpark`]: Thread::unpark
/// [`thread::park_timeout`]: park_timeout
/// [release sequence]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release_sequence
#[stable(feature = "rust1", since = "1.0.0")]
pub fn park() {
// SAFETY: park_timeout is called on the parker owned by this thread.
Expand Down

0 comments on commit 9de1d7c

Please sign in to comment.