Lars Hagström wrote:
Hi!
In a piece of legacy code I've had a few uses of the atomic operations inside Boost.Interprocess (yes, I know they're internal, but I had no other choice at the time, so sue me :-). I've been debugging a thread synchronization issue which ended up in me actually looking for a problem inside interprocess, and I believe that I found the error. The atomic_write32 function, when running gcc on intel platforms does not have a memory barrier, which causes my threads to not see changes that they should see.
A little bit of googling gave me the following link http://boost.2283326.n4.nabble.com/interprocess-atomic-write32-td4173289.htm..., which discusses exactly this issue.
I've now fixed my code to use Boost.Atomic instead of relying on boost interprocess internals, so I'm good, but I worry that the issue might affect boost.interprocess as well.
So I propose that atomic_write32 should be implemented using atomic_cas32.
There is no reason to implement atomic writes with CAS on x86. If atomic_write32 is supposed to be sequentially consistent, it should be implemented with XCHG. If it's only needed to have release semantics, an ordinary write should be used. All writes have release semantics on x86. The problem with the current implementation is not the lack of a hardware memory barrier, but the lack of a compiler memory barrier. On GCC, it's __asm__ __volatile__ ( "" ::: "memory" ). For release semantics, it ought to go before the store. Nowadays on GCC it might be best to use the built-in atomic intrinsics: https://gcc.gnu.org/onlinedocs/gcc-4.9.1/gcc/_005f_005fatomic-Builtins.html std::atomic would be even better but I don't think it works in C++03 mode.