
Roland Schwarz wrote:
There are 3: read_mb, write_mb and full_mb.
There are fifteen, in principle. The basic bidirectional ordering constraints are #LoadLoad, #LoadStore, #StoreLoad and #StoreStore, and a barrier can include any subset of them. In practice #StoreLoad usually implies a full barrier. A load.acquire can be emulated as load #LoadLoad | #LoadStore A store.release can be emulated as #LoadStore | #StoreStore store
full_mb disallows moving any read or write across the barrier, and so establishes total order.
Total order is a systemwide property of the memory model and can't necessarily be achieved with local barriers. It's possible for an SMP system to have full barriers and not deliver total order. As an example, if you have two CPUs execute // CPU #1 op1 full barrier op2 // CPU #2 op3 full barrier op4 then it is guaranteed that all CPUs will see op1 before op2 and op3 before op4, but it is not guaranteed that CPU #4 will see the same order of op1, op2, op3, and op4 as CPU #3. In principle, at least.