Std::sync synchronization semantics

C++ has explicit semantics for its equivalents of Mutex, RwLock, Barrier, etc., while Rust does not (at least anywhere I can find). Has there been any discussion on defining this? Is there perhaps a decision that has been reached somewhere but not documented?

Hmm, I think everyone knows what Mutex and RwLock do, is that in any way unclear?

Barrier is a much lower-level thing, related to atomics. Rust uses the same semantics for that as C++, and that is tricky to understand, but generally you do not need to go down to that level.

There is a bit of difference I think: C++ guarantees a consistent total order of mutex acquisitions and Rust might not.

What is documented isn't unclear enough to be unusable, but it would be much nicer if they had real guarantees around synchronization. It can just be one sentence, documented on the type, the lock/read/write methods, the guard types, or their drop impls. I hope at least one of those isn't too much to ask.

How do you know that? Given the other differences from C++'s latch (making it reusable and simplifying all methods into one), I wouldn't be comfortable making that assumption (not that I would for the other, more similar, types either).

Down to the level of using an item advertised in the "Higher-level synchronization objects" heading of the module? If you're thinking of std::atomic::fence, I should note that I was satisfied with that function's documentation, and the only minor problems I can see with it are the bullet points at the top (especially "fence - fence synchronization") not specifying exact requirements and the use of the word "dependence" throughout (which could be misinterpreted as the dependency-ordered before relation).

I'm not trying to be abrasive or get too caught up in specific types. While relying on outside knowledge and assumptions for common types and those with C++ analogues will satisfy some people, there are other types (like OnceLock or mpsc::Receiver) that are uncommon or different enough to simply need more documentation to be used correctly in complex situations. If anyone has even so much as a Zulip message or GitHub comment they can point to from someone with authority saying when and to what extent synchronization occurs, I'd be happy to create a PR to update the docs (though I may need guidance).

Perhaps the module level documentation would help. Yes, the high-level sync objects sync. That is their whole purpose.

I think you're confusing Barrier with fences. Barrier is built on Mutex and CondVar and is used to get several threads to wait and then all start some process together.

Fences are the much lower level thing that's used with atomics -- it's a way to make sure that when you communicate with another thread using an atomic (you can also use Ordering on the atomic ops for this), that all the other memory ends up properly synchronized so you don't end up reading stale values. it's a lot more complex than that, but if you're not writing unsafe code you may not need to worry about fences, since all the library functions that use atomics internally to synchronize and unsafe-ly communicate through memory should be using the proper Ordering and/or fences.