diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2023-06-21 15:45:15 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-06-21 15:45:15 +0200 |
| commit | 476798d4fd441375a865cc1dee1e6d5d790df3a2 (patch) | |
| tree | 6eb5da61bfd43881532c76d2e8e470a49ee25337 /compiler/rustc_codegen_llvm/src/errors.rs | |
| parent | 97bf23d26b1ffff46f071aa687945a6cf85a5914 (diff) | |
| parent | 3acb1d2b9b5f0ab85cb787250326c0571503f78c (diff) | |
| download | rust-476798d4fd441375a865cc1dee1e6d5d790df3a2.tar.gz rust-476798d4fd441375a865cc1dee1e6d5d790df3a2.zip | |
Rollup merge of #99587 - ibraheemdev:park-orderings, r=m-ou-se
Document memory orderings of `thread::{park, unpark}`
Document `thread::park/unpark` as having acquire/release synchronization. Without that guarantee, even the example in the documentation can deadlock:
```rust
let flag = Arc::new(AtomicBool::new(false));
let t2 = thread::spawn(move || {
while !flag.load(Ordering::Acquire) {
thread::park();
}
});
flag.store(true, Ordering::Release);
t2.thread().unpark();
// t1: flag.store(true)
// t1: thread.unpark()
// t2: flag.load() == false
// t2 now parks, is immediately unblocked but never
// acquires the flag, and thus spins forever
```
Multiple calls to `unpark` should also maintain a release sequence to make sure operations released by previous `unpark`s are not lost:
```rust
let a = Arc::new(AtomicBool::new(false));
let b = Arc::new(AtomicBool::new(false));
let t2 = thread::spawn(move || {
while !a.load(Ordering::Acquire) || !b.load(Ordering::Acquire) {
thread::park();
}
});
thread::spawn(move || {
a.store(true, Ordering::Release);
t2.thread().unpark();
});
b.store(true, Ordering::Release);
t2.thread().unpark();
// t1: a.store(true)
// t1: t2.unpark()
// t3: b.store(true)
// t3: t2.unpark()
// t2 now parks, is immediately unblocked but never
// acquires the store of `a`, only the store of `b` which
// was released by the most recent unpark, and thus spins forever
```
This is of course a contrived example, but is reasonable to rely upon in real code.
Note that all implementations of park/unpark already comply with the rules, it's just undocumented.
Diffstat (limited to 'compiler/rustc_codegen_llvm/src/errors.rs')
0 files changed, 0 insertions, 0 deletions
