-
Notifications
You must be signed in to change notification settings - Fork 12.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Relax SeqCst ordering in standard library. #122729
Conversation
SeqCst is unnecessary here.
SeqCst is unnecessary here.
Relaxed is enough here.
SeqCst is unnecessary.
Relaxed is enough to make sure this `swap` results in `true` only once.
No need for SeqCst. Release+Acquire is the right memory ordering for a mutex.
SeqCst is unnecessary here.
SeqCst is unnecessary here.
SeqCst is unnecessary. Release+Acquire is the right ordering for a mutex.
Relaxed is enough to ensure fetch_add(1) returns each integer exactly once.
SeqCst is unnecessary. Release+Acquire is the right ordering for a mutex.
The SeqCst wasn't synchronizing with anything. Relaxed is enough.
Could we run the testsuite on miri just in case something was missed? It's easy to make mistakes with insufficient memory orderings. Other than that, I strongly agree with the premise that |
@RalfJung how do we run Miri on the std test suite in this PR? |
You can use rustup-toolchain-install-master to install the toolchain for the commit this PR is based on, adding all the components required for Miri. (Something like Then check out https://github.com/rust-lang/miri-test-libstd/, in there add an override for the above toolchain, and run something like
The first argument is the crate to test. The rest ( The
I agree with that. However, I also would say the same about "Relaxed". These accesses are incredibly poorly behaved. (See llvm/llvm-project#64188 for a recent example of trouble they are causing for standard compiler optimizations.) IMO one should always use the release/acquire modes unless there is a strong reason to use anything else, and any deviation from this requires a justifying comment. So I'm not happy to see a proliferation of "Relaxed" in this PR, in particular in docs. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good to me, modulo the comment!
That example you link is not just about a single atomic variable with relaxed operations, it's about an interaction of pointers+acquire-release+relaxed (and some variable whose address hasn't escaped/been exposed at the time of the release operation). Such a complex situation has very little to do with the simple cases we have in the standard library. This PR is about very simple patterns, such as using |
SeqCst isn't necessary in any of these cases.
Relax SeqCst ordering in standard library. Every single SeqCst in the standard library is unnecessary. In all cases, Relaxed or Release+Acquire was sufficient. As I [wrote](https://marabos.nl/atomics/memory-ordering.html#common-misconceptions) in my book on atomics: > [..] when reading code, SeqCst basically tells the reader: "this operation depends on the total order of every single SeqCst operation in the program," which is an incredibly far-reaching claim. The same code would likely be easier to review and verify if it used weaker memory ordering instead, if possible. For example, Release effectively tells the reader: "this relates to an acquire operation on the same variable," which involves far fewer considerations when forming an understanding of the code. > > It is advisable to see SeqCst as a warning sign. Seeing it in the wild often means that either something complicated is going on, or simply that the author did not take the time to analyze their memory ordering related assumptions, both of which are reasons for extra scrutiny. r? `@Amanieu` `@joboet`
…llaumeGomez Rollup of 8 pull requests Successful merges: - rust-lang#122494 (Simplify key-based thread locals) - rust-lang#122644 (pattern analysis: add a custom test harness) - rust-lang#122723 (Use same file permissions for ar_archive_writer as the LLVM archive writer) - rust-lang#122729 (Relax SeqCst ordering in standard library.) - rust-lang#122740 (use more accurate terminology) - rust-lang#122764 (coverage: Remove incorrect assertions from counter allocation) - rust-lang#122765 (Add `usize::MAX` arg tests for Vec) - rust-lang#122776 (Rename `hir::Let` into `hir::LetExpr`) r? `@ghost` `@rustbot` modify labels: rollup
Relax SeqCst ordering in standard library. Every single SeqCst in the standard library is unnecessary. In all cases, Relaxed or Release+Acquire was sufficient. As I [wrote](https://marabos.nl/atomics/memory-ordering.html#common-misconceptions) in my book on atomics: > [..] when reading code, SeqCst basically tells the reader: "this operation depends on the total order of every single SeqCst operation in the program," which is an incredibly far-reaching claim. The same code would likely be easier to review and verify if it used weaker memory ordering instead, if possible. For example, Release effectively tells the reader: "this relates to an acquire operation on the same variable," which involves far fewer considerations when forming an understanding of the code. > > It is advisable to see SeqCst as a warning sign. Seeing it in the wild often means that either something complicated is going on, or simply that the author did not take the time to analyze their memory ordering related assumptions, both of which are reasons for extra scrutiny. r? ``@Amanieu`` ``@joboet``
…llaumeGomez Rollup of 8 pull requests Successful merges: - rust-lang#122644 (pattern analysis: add a custom test harness) - rust-lang#122696 (Add bare metal riscv32 target.) - rust-lang#122723 (Use same file permissions for ar_archive_writer as the LLVM archive writer) - rust-lang#122729 (Relax SeqCst ordering in standard library.) - rust-lang#122740 (use more accurate terminology) - rust-lang#122764 (coverage: Remove incorrect assertions from counter allocation) - rust-lang#122765 (Add `usize::MAX` arg tests for Vec) - rust-lang#122776 (Rename `hir::Let` into `hir::LetExpr`) r? `@ghost` `@rustbot` modify labels: rollup
Relax SeqCst ordering in standard library. Every single SeqCst in the standard library is unnecessary. In all cases, Relaxed or Release+Acquire was sufficient. As I [wrote](https://marabos.nl/atomics/memory-ordering.html#common-misconceptions) in my book on atomics: > [..] when reading code, SeqCst basically tells the reader: "this operation depends on the total order of every single SeqCst operation in the program," which is an incredibly far-reaching claim. The same code would likely be easier to review and verify if it used weaker memory ordering instead, if possible. For example, Release effectively tells the reader: "this relates to an acquire operation on the same variable," which involves far fewer considerations when forming an understanding of the code. > > It is advisable to see SeqCst as a warning sign. Seeing it in the wild often means that either something complicated is going on, or simply that the author did not take the time to analyze their memory ordering related assumptions, both of which are reasons for extra scrutiny. r? ```@Amanieu``` ```@joboet```
…iaskrgr Rollup of 10 pull requests Successful merges: - rust-lang#122545 (Ignore paths from expansion in `unused_qualifications`) - rust-lang#122644 (pattern analysis: add a custom test harness) - rust-lang#122696 (Add bare metal riscv32 target.) - rust-lang#122729 (Relax SeqCst ordering in standard library.) - rust-lang#122740 (use more accurate terminology) - rust-lang#122749 (make `type_flags(ReError) & HAS_ERROR`) - rust-lang#122764 (coverage: Remove incorrect assertions from counter allocation) - rust-lang#122765 (Add `usize::MAX` arg tests for Vec) - rust-lang#122776 (Rename `hir::Let` into `hir::LetExpr`) - rust-lang#122786 (compiletest: Introduce `remove_and_create_dir_all()` helper) r? `@ghost` `@rustbot` modify labels: rollup
Rollup of 8 pull requests Successful merges: - rust-lang#122545 (Ignore paths from expansion in `unused_qualifications`) - rust-lang#122729 (Relax SeqCst ordering in standard library.) - rust-lang#122740 (use more accurate terminology) - rust-lang#122749 (make `type_flags(ReError) & HAS_ERROR`) - rust-lang#122764 (coverage: Remove incorrect assertions from counter allocation) - rust-lang#122765 (Add `usize::MAX` arg tests for Vec) - rust-lang#122776 (Rename `hir::Let` into `hir::LetExpr`) - rust-lang#122786 (compiletest: Introduce `remove_and_create_dir_all()` helper) r? `@ghost` `@rustbot` modify labels: rollup
Rollup merge of rust-lang#122729 - m-ou-se:relax, r=Amanieu Relax SeqCst ordering in standard library. Every single SeqCst in the standard library is unnecessary. In all cases, Relaxed or Release+Acquire was sufficient. As I [wrote](https://marabos.nl/atomics/memory-ordering.html#common-misconceptions) in my book on atomics: > [..] when reading code, SeqCst basically tells the reader: "this operation depends on the total order of every single SeqCst operation in the program," which is an incredibly far-reaching claim. The same code would likely be easier to review and verify if it used weaker memory ordering instead, if possible. For example, Release effectively tells the reader: "this relates to an acquire operation on the same variable," which involves far fewer considerations when forming an understanding of the code. > > It is advisable to see SeqCst as a warning sign. Seeing it in the wild often means that either something complicated is going on, or simply that the author did not take the time to analyze their memory ordering related assumptions, both of which are reasons for extra scrutiny. r? ````@Amanieu```` ````@joboet````
@m-ou-se btw, given your stance on SeqCst (which I agree with), I wonder if you'd be open to reviving rust-lang/rfcs#2503 in one shape or another? IOW, providing some way to say "give me release and/or acquire, whatever fits for this operation", without the risk of accidentally using |
@RalfJung I've seen a lot of cases where people want (or think they want ^^') an "acquire store" or "release load" (which don't exist). With something like |
Hm, yes that is fair. I think I am mostly worried about accidentally using Acquire/Release as the success ordering of an RMW, which introduces Relaxed semantics without Relaxed appearing in the code. |
I imagine we could have |
This replaces all SeqCst atomic operations with Release, Acquire or AcqRel. Also see rust-lang/rust#122729.
This replaces all SeqCst atomic operations with Release, Acquire or AcqRel. Also see rust-lang/rust#122729.
This replaces all SeqCst atomic operations with Release, Acquire or AcqRel. Also see rust-lang/rust#122729.
This replaces all SeqCst atomic operations with Release, Acquire or AcqRel. Also see rust-lang/rust#122729.
This replaces all SeqCst atomic operations with Release, Acquire or AcqRel. Also see rust-lang/rust#122729.
This replaces all SeqCst atomic operations with Release, Acquire or AcqRel. Also see rust-lang/rust#122729.
Every single SeqCst in the standard library is unnecessary. In all cases, Relaxed or Release+Acquire was sufficient.
As I wrote in my book on atomics:
r? @Amanieu @joboet