What I assume they’re thinking of is, if the compiler can determine that the lock is scoped and the scoped code only reads from shared memory, then it only needs a sequence point (a read barrier).
I don’t think it’s true because if you don’t “hold” the mutex there’s no guarantee that the mutex-protected data is consistent, unless it’s atomic at which point you’re probably better off optimising to an atomic read. Which compilers are unlikely to bother with either way, because optimising atomic operations would be both risky and low-return.
Right. Even if the mutex is protecting a is a single memory location, holding a mutex is still observable behavior (there is a total orders of all critical sections at the very least), and eliding it is questionable.
Isn't that exactly what SeqCst atomic access gives you in this case? Assuming that the critical sections are restricted to doing read-modify-write of an atomic-sized memory location - which would have to be enforced at compile time or require whole-program analysis.
But again, if you only have an atomic-sized memory location, and you bother writing an optimisation for atomic stuff, why bother with barriers when you could just perform an atomic update?
Also SeqCst is way overkill for a mutex, that is literally the use case for acquire and release semantics, the two barriers were named after the lock operation.
there is a total order of all critical sections on a specific mutex, but I don't think it is technically part of the same total order of seqcst atomics (although it might in practice). This sort of stuff is extremely subtle.
I don’t think it’s true because if you don’t “hold” the mutex there’s no guarantee that the mutex-protected data is consistent, unless it’s atomic at which point you’re probably better off optimising to an atomic read. Which compilers are unlikely to bother with either way, because optimising atomic operations would be both risky and low-return.