cce Subj : Re: Memory visibility and MS Interlocked instructions To : comp.programming.threads From : John Hickin Date : Thu Aug 25 2005 02:31 pm I think they are confused, not you :-) At the risk of falling into a trap, here goes: LONG volatile fValueHasBeenComputedState = 0; void CacheComputedValue() { switch (InterlockedExchangeAdd(&fValueHasBeenComputedState,(LONG)1)) { case 0; iValue = ComputeValue(); InterlockedExchange(&fValueHasBeenComputedState, 2); break; case 1: while(InterlockedExchangeAdd(&fValueHasBeenComputedState,(LONG)0) == (LONG)1) { } // fall through default: // nothing to do ; } } "Scott Meyers" wrote in message news:11grrhq40j3p4ba@corp.supernews.com... > Suppose thread W (the writer) writes a value to variable x and thread R > (the reader) later reads the value of x. On a relaxed memory architecture, > my understanding has been that to guarantee that R sees the value written > by W, W must follow the write with a release membar and R must precede the > read with an acquire membar. The membars might be used directly, or they > might be used indirectly via locks, e.g., both W and R could access x after > acquiring the correct mutex. Conceptually (though not operationally), I > think of the release membar as forcing W's local memory to be flushed to > main memory and the acquire membar as forcing R's local memory to be > synched with main memory. > > What's important about my undertanding is that guaranteeing that R sees the > correct value depends on both W and R taking actions. It's not enough for > W alone to use a membar or a lock, and it's not enough for R alone to use a > membar or a lock: both must do something to ensure that W's write is > visible to R. > > This model does not seem to be consistent with the documented semantics of > Microsoft's Interlocked instructions at > http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/about_synchronization.asp, > which "ensure that previous read and write requests have completed and are > made visible to other processors, and ensure that that no subsequent read > or write requests have started." The page gives this example: > > BOOL volatile fValueHasBeenComputed = FALSE; > > void CacheComputedValue() > { > if (!fValueHasBeenComputed) > { > iValue = ComputeValue(); > InterlockedExchange((LONG*)&fValueHasBeenComputed, TRUE); > } > } > > The InterlockedExchange function ensures that the value of iValue is > updated for all processors before the value of fValueHasBeenComputed is > set to TRUE. > > What confuses me is that here only the writer needs to take an action to > guarantee that readers will see things in the proper order, where my > understanding had been that the reader, too, would have to take some action > before reading iValue and fValueHasBeenComputed to ensure that it didn't > get a stale value for one or both. > > Obviously I'm missing something. Can somebody please clear up my > confusion? > > Thanks, > > Scott . 0