Skip to content

Commit 9de1d7c

Browse files
committed
document memory orderings of thread::{park, unpark}
1 parent 31b9b01 commit 9de1d7c

File tree

1 file changed

+19
-9
lines changed

1 file changed

+19
-9
lines changed

library/std/src/thread/mod.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -845,7 +845,7 @@ pub fn sleep(dur: Duration) {
845845
/// A call to `park` does not guarantee that the thread will remain parked
846846
/// forever, and callers should be prepared for this possibility.
847847
///
848-
/// # park and unpark
848+
/// # `park` and `unpark`
849849
///
850850
/// Every thread is equipped with some basic low-level blocking support, via the
851851
/// [`thread::park`][`park`] function and [`thread::Thread::unpark`][`unpark`]
@@ -866,14 +866,6 @@ pub fn sleep(dur: Duration) {
866866
/// if it wasn't already. Because the token is initially absent, [`unpark`]
867867
/// followed by [`park`] will result in the second call returning immediately.
868868
///
869-
/// In other words, each [`Thread`] acts a bit like a spinlock that can be
870-
/// locked and unlocked using `park` and `unpark`.
871-
///
872-
/// Notice that being unblocked does not imply any synchronization with someone
873-
/// that unparked this thread, it could also be spurious.
874-
/// For example, it would be a valid, but inefficient, implementation to make both [`park`] and
875-
/// [`unpark`] return immediately without doing anything.
876-
///
877869
/// The API is typically used by acquiring a handle to the current thread,
878870
/// placing that handle in a shared data structure so that other threads can
879871
/// find it, and then `park`ing in a loop. When some desired condition is met, another
@@ -887,6 +879,23 @@ pub fn sleep(dur: Duration) {
887879
///
888880
/// * It can be implemented very efficiently on many platforms.
889881
///
882+
/// # Memory Orderings
883+
///
884+
/// Calls to `park` _synchronize-with_ calls to `unpark`, meaning that memory
885+
/// operations performed before a call to `unpark` are made visible to the thread that
886+
/// consumes the token and returns from `park`. Note that all `park` and `unpark`
887+
/// operations for a given thread form a total order and `park` synchronizes-with
888+
/// _all_ prior `unpark` operations.
889+
///
890+
/// In atomic ordering terms, `unpark` performs a `Release` operation and `park`
891+
/// performs the corresponding `Acquire` operation. Calls to `unpark` for the same
892+
/// thread form a [release sequence].
893+
///
894+
/// Notice that being unblocked does not imply any synchronization with someone that
895+
/// unparked this thread, it could also be spurious. For example, it would be a valid,
896+
/// but inefficient, implementation to make both park and unpark return immediately
897+
/// without doing anything.
898+
///
890899
/// # Examples
891900
///
892901
/// ```
@@ -926,6 +935,7 @@ pub fn sleep(dur: Duration) {
926935
///
927936
/// [`unpark`]: Thread::unpark
928937
/// [`thread::park_timeout`]: park_timeout
938+
/// [release sequence]: https://en.cppreference.com/w/cpp/atomic/memory_order#Release_sequence
929939
#[stable(feature = "rust1", since = "1.0.0")]
930940
pub fn park() {
931941
// SAFETY: park_timeout is called on the parker owned by this thread.

0 commit comments

Comments
 (0)