Consider several threads executing concurrently the following code:
long gf = 0;// global variable or class member
//...
if (InterlockedCompareExchange(&gf, 1, 0)==0) // lock cmpxchg
{
// some exclusive code - must not execute in concurrent
gf = 0; // this is ok ? or need
//InterlockedExchange(&gf, 0); // [lock] xchg
}
Treat the code above as C-like pseudo-code, which will be translated more-or-less directly into assembly without the usual concessions to compiler optimizations such as re-odering and store elimination.
So after some thread exclusively acquires flag gf
- to exit from the critical region is it enough to write a zero (as in gf = 0
) or does this need to be interlocked - InterlockedExchange(&gf, 0)
?
If both are OK, which is better from a performance view, assuming that with high probability that several cores concurrently call InterlockedCompareExchange(&gf, 1, 0)
?
Several threads periodically execute this code (from several places, when some events fire) and it is important that the next thread again enters the critical region as soon as possible after it freed.