Re: What in C++11 prohibits mutex operations from being reordered?
On Apr 4, 12:43 am, =D6=F6 Tiib <oot...@hot.ee> wrote:
)
{
// these lines can't be reordered in any way
data=42;
std::atomic_thread_fence(std::memory_order_release);
ready.store(true,std::memory_order_relaxed);
}
void thread_2()
{
if(ready.load(std::memory_order_relaxed))
{
// these lines can't be reordered
std::atomic_thread_fence(std::memory_order_acquir=
e);
std::cout<<"data="<<data<<std::endl;
}
}
So you find above very basic. Relaxed ready.store can't become
visible in thread 2 before data=42. Yet you do not for some reason see =
any relation with the mutex2 locking that you somehow feel may happen and
become visible in thread 2 before data=42 like that:
void thread_1()
{
// these lines can't be reordered in any way
data=42;
std::atomic_thread_fence(std::memory_order_release);
mutex2.lock();
// ...
// ...
}
I am in difficulties to understand what is the reason why you see
the relaxed atomic bool access can be ordered better than mutex lock?
I now see that you made an argument and intended to demonstrate with
your code that the reordering I am talking about can not happen.
I agree that "Relaxed ready.store can't become visible in thread 2
before data=42". I.e. I agree that in the code
1: data=42;
2: std::atomic_thread_fence(std::memory_order_release);
3: ready.store(true,std::memory_order_relaxed);
lines 1 and 3 must not be reordered by compiler.
And I do agree that in the code
1: data=42;
2: std::atomic_thread_fence(std::memory_order_release);
3: mutex2.lock();
lines 1 and 3 must not be reordered by compiler.
But if we are talking about implementing of mutexes and if we decide
to use fences (as you are doing), our code will rather look like:
1: data=42;
2: std::atomic_thread_fence(std::memory_order_release);
3: mark mutex1 as unlocked
4: mutex2.lock();
Here line 1 is a last line in the code section protected by mutex1,
lines 2 and 3 - pseudo-implementation of mutex1.unlock(),
line 4 is a lock on mutex 2.
What line 2 does - it prevents data=42 to sink out of critical
section, so it is guaranteed that data=42 is done before mutex1 is
marked as unlocked (the later may be relaxed, yet must be an atomic
operation).
So in the end, lines 3 and 4 may still be reordered, a fence on line 2
does not prohibit it. And that is equivalent to locking mutex2 before
unlocking mutex1.
Regards, Michael