

In particular, you might notice that the docs for Ordering and fence make no mention of how they interact with volatile memory accesses, and that's because they do not.
Berkeley upc memory fence code#
In response to another answer on this question that flat stated that fence and barrier are equivalent, I raised this case on the Rust Unsafe Code Guidelines issue tracker and got some clarifications. These are the sorts of barriers described in considerable detail in the Linux Kernel's documentation on memory barriers. For cases like that, you need a different sort of memory barrier. In particular, fence helps you reason about which atomic memory operations are visible to which other atomic memory operations - it does not help you reason about whether a particular stored value has made it all the way through the memory hierarchy and onto a particular level of the bus. (This is because I tend to work low in the stack, so this may not apply to your case.) In this case, you are likely performing volatile memory accesses, and you want barriers that are stronger than what fence offers. The most common place that I employ memory barriers is to reason about completion of writes to memory-mapped I/O in low level code, such as drivers. The nice thing about the C++ docs is that they discuss each interaction case between load/store/fence and load/store/fence. The C++ docs are much higher in jargon, but if you read slowly it's not actually more complex than the Rust docs - just jargony. I know, we're not writing C++, but Rust inherits a lot of this behavior from LLVM, and LLVM tries to follow the C++ standard here. However, if you want all the interactions precisely laid out, I'm afraid you must look to a different source: the equivalent C++ docs. IMO the docs in this area could use some love. The docs for fence go a little ways to repair that. This ordering is only applicable for operations that can perform a store. However, at the time of this writing, it's misleading for your specific question, because it says things like This is a pretty good description of how operations with different Ordering interact, with less jargon than a lot of references in this area (atomic memory orderings). Here are the docs I suggest reading if you want to learn more.įirst, Rust's docs for the Ordering type. The terms folks use for describing the various atomic conditions can be a little daunting at first, but they are pretty well defined in the docs, though at the time of this writing there are some omissions. Rust's std::sync::atomic::fence provides an atomic fence operation, which provides synchronization between other atomic fences and atomic memory operations. This is not what you asked about, but people often accidentally use this in place of a real barrier, which makes them sad later.

More general memory barrier: controls the order of actual operations against memory or memory-mapped I/O.Atomic fence: controls the order in which observers can see the effects of atomic memory operations.For the purposes of this discussion I'll distinguish informally between three kinds of beasts: A "fence" in this context is a kind of memory barrier.
