This is using atomic - fence synchronization, one of the 3 synchronization modes available with std::atomic_thread_fence, alongside fence - atomic and fence - fence.
This prompted me to realize that the Rust "equivalent", our own atomic::fence, only documents fence - fence synchronization.
Is this a documentation issue? Or does Rust not support atomic - fence & fence - atomic synchronizations?
I thought that Rust copied C/C++ memory model, so it's somewhat surprising (and unhelpful) to see a divergence.
Looking closer, I do think the wording is correct & complete, if a bit buried. In particular, the large diagram for fence - fence synchronization -- which is very useful -- takes on a disproportionately large amount of space.
I'll have to mull on the wording. I think clearly enunciating the 3 usecases at the top and then having one subsection with diagram for each usecase would make it much clearer. It would also ensure that the user understands how to do atomic - fence or fence - atomic synchronization properly, as it's not necessarily obvious how the operations on the "fence" side need to be organized from just reading the doc.
The questions are already answered, but do note that the support should also be indicated[1] that Rust's reference counting (Arc) does in fact do the exact same thing (increment Relaxed and decrement Release - the latter using a fence before moving on towards destruction[2]).
it's not conclusive proof on its own that it's implemented this way, as std does sometimes also do things that downstream code isn't allowed to rely on, but at least it can be a strong clue towards Rust being equivalent here ↩︎
there are some extra steps afterwards, but those only exist because there's also a weak pointer, and also operationally, at least calling the drop (glue) for the contained value is the very next thing that happens - the weak pointer-involving extra steps are only coming into okay in order to also - eventually - deallocate the immediate/shallow heap memory for the value behind the Arc↩︎