
Ilya Sokolov wrote:
On Thu, 25 Aug 2011 02:27:11 +0600, Dave Abrahams <dave@boostpro.com> wrote:
on Wed Aug 24 2011, Alexander Terekhov <terekhov-AT-web.de> wrote:
Dave Abrahams wrote:
All I'm saying here is that a C++11 default atomic int is equivalent to an int, coupled with an associated mutex, where accesses to the int are always protected by locking the associated mutex. If you're seriously disagreeing with *that*, please say explicitly on what grounds.
int i; mutex mi, int j; mutex mj;
mi.lock(); i = 1; mi.unlock();
mj.lock(); j = 2; mj.unlock();
can be transformed to
multi_lock(mi, mj); // deadlock free j = 2; i = 1; mi.unlock(); mj.unlock();
and thus result in reodering i = 1 and j = 2.
With C++11 default atomics (SC) for i and j such reodering is prohibited.
As it is with C++11 mutexes, IIUC. Another thread that locks the same mutexes is not allowed to observe the write to j before the write to i. If you have contrary evidence, please point to it.
AFAIK, in the example above another thread can't observe reordering without introducing UB.
I meant "observed" as in "check the sequence of writes in the generated code". But int can be simply changed to relaxed atomic<int> so that another thread can observe reordering without UB.
Here is a more correct example:
int x = 0; int y = 0; int r1, r2; mutex mx, my;
// Thread 1: mx.lock(); x = 1; mx.unlock();
my.lock(); r1 = y; my.unlock();
// Thread 2: my.lock(); y = 1; my.unlock();
mx.lock(); r2 = x; mx.unlock();
Now, it is possible that r1 == r2 == 0, ...
Nope, it is impossible. Same as with // Thread 1: multi_lock(mx, my); // deadlock free r1 = y; x = 1; mx.unlock(); my.unlock(); // Thread 2: multi_lock(my, mx); // deadlock free r2 = x; y = 1; my.unlock(); mx.unlock(); regards, alexander.