> static int g_state = 0;
> static bool volatile g_done = 0;
>
>
> void thread_1(thread& t)
> {
> g_state = 666;
> t.membar();
> g_done = true;
> }
Let's examine that, assuming mutex lock is acquire and unlock is release:
__________________________________________________________
void thread_1(thread& t)
{
S1: g_state = 666;
t.membar()
{
M1: lock2();
M2: unlock1();
M3: lock1();
M4: unlock2();
};
S2: g_done = true;
}
__________________________________________________________
Okay. I see something important here:
1. M2 and M3 should never hoist above M1.
2. M2 and M3 should never sink below M4.
3. M3 should never hoist above M2
4. M2 should never sink below M3
This allows for another important observation:
1. S1 should never sink below M2
2. S2 should never hoist above M3
AFAICT, that gives you something that is analogous to a
`std::memory_order_acq_rel' barrier.
> Would that work?
Yes. BTW, I use the same method for the lock-based version of vZOOM:
http://groups.google.ru/group/comp.programming.threads/msg/59e9b6e427b4a144
except that I allow the polling thread to synchronize with reader thread by
actually acquiring the per-thread owner_lock's.
One more thing, don't forget about asymmetric synchronization. If a mutex
uses that type of sync, then you basically need to have a "foreign" thread
try to acquire the mutex in order to force a memory barrier on the
"preferred" thread. This is one of the reasons why I allow the polling logic
to sync on the owner_locks.
[...]
Sorry about that.