about summary refs log tree commit diff
path: root/compiler/rustc_codegen_llvm/src/errors.rs
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2023-06-21 15:45:15 +0200
committerGitHub <noreply@github.com>2023-06-21 15:45:15 +0200
commit476798d4fd441375a865cc1dee1e6d5d790df3a2 (patch)
tree6eb5da61bfd43881532c76d2e8e470a49ee25337 /compiler/rustc_codegen_llvm/src/errors.rs
parent97bf23d26b1ffff46f071aa687945a6cf85a5914 (diff)
parent3acb1d2b9b5f0ab85cb787250326c0571503f78c (diff)
downloadrust-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