about summary refs log tree commit diff
path: root/library/std/src
diff options
context:
space:
mode:
authorMara Bos <m-ou.se@m-ou.se>2020-09-20 00:35:39 +0200
committerMara Bos <m-ou.se@m-ou.se>2020-09-27 11:56:43 +0200
commit4301b5c1cc9652247b1c465d304ff9c94df294ef (patch)
treed5a428c6a0beb354bfc466573575dceef697d891 /library/std/src
parent485f882d7713b0e0b864fc8b21368910e5b8b0a7 (diff)
downloadrust-4301b5c1cc9652247b1c465d304ff9c94df294ef.tar.gz
rust-4301b5c1cc9652247b1c465d304ff9c94df294ef.zip
Add notes about memory ordering to futex parker implementation.
Diffstat (limited to 'library/std/src')
-rw-r--r--library/std/src/thread/parker/futex.rs20
1 files changed, 20 insertions, 0 deletions
diff --git a/library/std/src/thread/parker/futex.rs b/library/std/src/thread/parker/futex.rs
index 2d7a7770508..a5d4927dcc5 100644
--- a/library/std/src/thread/parker/futex.rs
+++ b/library/std/src/thread/parker/futex.rs
@@ -11,6 +11,26 @@ pub struct Parker {
     state: AtomicI32,
 }
 
+// Notes about memory ordering:
+//
+// Memory ordering is only relevant for the relative ordering of operations
+// between different variables. Even Ordering::Relaxed guarantees a
+// monotonic/consistent order when looking at just a single atomic variable.
+//
+// So, since this parker is just a single atomic variable, we only need to look
+// at the ordering guarantees we need to provide to the 'outside world'.
+//
+// The only memory ordering guarantee that parking and unparking provide, is
+// that things which happened before unpark() are visible on the thread
+// returning from park() afterwards. Otherwise, it was effectively unparked
+// before unpark() was called while still consuming the 'token'.
+//
+// In other words, unpark() needs to synchronize with the part of park() that
+// consumes the token and returns.
+//
+// This is done with a release-acquire synchronization, by using
+// Ordering::Release when writing NOTIFIED (the 'token') in unpark(), and using
+// Ordering::Acquire when checking for this state in park().
 impl Parker {
     #[inline]
     pub const fn new() -> Self {