I have read the article Synchronization and Multiprocessor Issues and I have a question about InterlockedCompareExchange and InterlockedExchange. The question is actually about the last example in the article. They have two variables iValue
and fValueHasBeenComputed
and in CacheComputedValue()
they modify each of them using InterlockedExchange
:
InterlockedExchange ((LONG*)&iValue, (LONG)ComputeValue()); // don't understand
InterlockedExchange ((LONG*)&fValueHasBeenComputed, TRUE); // understand
I understand that I can use InterlockedExchange
for modifing iValue
but is it enought just to do
iValue = ComputeValue();
So is it actually necessary to use InterlockedExchange
to set iValue? Or other threads will see iValue correctly even if iValue = ComputeValue();
. I mean the other threads will see iValue correctly because there is InterlockedExchange
after it.
There is also the paper A Principle-Based Sequential Memory Model for Microsoft Native Code Platforms. There is the 3.1.1 example with more or less the same code. One of the recomendation Make y interlocked
. Notice - not both y
and x
.
Update
Just to clarify the question. The issue is that I see a contradiction. The example from "Synchronization and Multiprocessor Issues" uses two InterlockedExchange
. On the contrary, in the example 3.1.1 "Basic Reodering" (which I think is quite similar to the first example) Herb Sutter gives this recomendation
"Make y interlocked: If y is interlocked, then there is no race on y because it is atomically updatable,and there is no race on x because a -> b -> d."
. In this draft Herb do not use two interlocked variable (If I am right he means use InterlockedExchange
only for y
).