I have a small test application that executes two threads simultaneously. One increments a static long _value
, the other one decrements it. I\'ve ensured with
The CLR memory model guarantees (requires) that loads/stores can't cross a fence. It's up to the CLR implementers to enforce this on real hardware, which they do. However, this is based on the advertised / understood behavior of the hardware, which can be wrong.
Cache coherence in this case does not depend on lock
. If you use lock
statement it ensures that your assembler commands are not mixed.
a += b
is not an atomic to processor, it looks like:
And without lock it may be:
But it's not about cache coherence, it's a more high-level feature.
So, lock
does not ensures that the caches are synchronized. Cache synchronization is a processor internal feature which does not depend on code. You can read about it here.
When one core writes a value to memory and then when the second core try to read that value it won't have the actual copy in its cache unless its cache entry is invalidated so a cache miss occurs. And this cache miss forces cache entry to be updated to actual value.
The lock
keyword is just syntactic sugar for a pair of System.Threading.Monitor.Enter()
and System.Threading.Monitor.Exit()
calls. The implementations of Monitor.Enter()
and Monitor.Exit()
put up a memory fence which entails performing architecture appropriate cache flushing. So your other thread won't proceed until it can see the stores that results from the execution of the locked section.