Isn't this case discussed at the end of the article?
C++ committee member Tony Van Eerd commented on reddit that with std::memory_order_acquire and two locks a and b; calls to a.unlock(); b.lock() and lock() for different locks could be reordered to b.lock(); a.unlock(); and introduce a potential deadlock. I don’t think that’s true. Reading section 6.9.2.1 Data races (paragraph 9) of the C++ standard] no loads or stores can bed moved into or out from between a load-acquire and store-release pair.
It's true that the compiler can't move reads/write out from between a load-acquire and store-release pair, but in my understanding it can certainly move reads/writes into the pair. Or can someone point me to the exact section of the standard where this is prohibited?
I think my stack overflow link above gives a more satisfying explanation on why the example can't deadlock.
Yes, it's the same example, but the answer appears to be subtly different. Acquire and release are only "one-way barriers". Consider the link in the sibling comment by spacechild1.
Comments
Isn't this case discussed at the end of the article?
It's true that the compiler can't move reads/write out from between a load-acquire and store-release pair, but in my understanding it can certainly move reads/writes into the pair. Or can someone point me to the exact section of the standard where this is prohibited?
I think my stack overflow link above gives a more satisfying explanation on why the example can't deadlock.
I now think it's actually this part of the standard that prevents it: http://eel.is/c++draft/intro.multithread#intro.progress-7
Basically a compiler can not optimize a non-deadlocking program into a potentially deadlocking one.
Yes, it's the same example, but the answer appears to be subtly different. Acquire and release are only "one-way barriers". Consider the link in the sibling comment by spacechild1.