noctonura
noctonura

Reputation: 13121

Do Interlocked.Xxx methods guarantee value updated in all data caches?

Example:

Thread a:  Interlocked.Increment(ref x);

Thread b:  int currentValue = x;

Assuming thread b executes after thread a, is "currentValue" in thread b guaranteed to be the incremented value? Or, does thread b need to do a Thread.VolatileRead(ref x)?

Upvotes: 5

Views: 322

Answers (2)

Marc Gravell
Marc Gravell

Reputation: 1062745

As I understand it, Interlocked is only guaranteed when accessed by other Interlocked methods. This may be especially important when talking about 64-bit values on x86 systems, where it cannot be guaranteed to be atomic, so torn values are a concern. A good trick for robustly reading a value that can be changed by Interlocked is CompareExchange:

int val = Interlocked.CompareExchange(ref field, 0, 0);

This mutates the value of field to 0, but only if the old value was 0 - otherwise it does nothing. Either way the old value is returned. So basically: it reads the value without ever changing it, and is safe vs other Interlocked methods.

Upvotes: 3

Eric J.
Eric J.

Reputation: 150108

Technically that depends on the CPU .NET is running on, but for any common CPU the answer is yes, cache coherency is guaranteed for an Interlocked.Increment. It acts as a memory barrier as required by MESI.

a CPU can have in its cache a line which is invalid, but where it doesn't yet know that line is invalid - the invalidation queue contains the invalidation which hasn't yet been acted upon. (The invalidation queue is on the other "side" of the cache; the CPU can't scan it, as it can the store buffer). As a result, memory barriers are required.

http://en.wikipedia.org/wiki/MESI_protocol (x86)

MOESI (used on AMD64 chips) is quite similar:

http://en.wikipedia.org/wiki/MOESI_protocol (AMD64)

Upvotes: 5

Related Questions