It seems the controversial point is whether such out-of-order writes can occur with the .NET 2.0 memory model. Vance Morrison has written an article [1] where he seems to say no (in this case), so volatile (or explicit memory barrier) are not needed. Other sources (such as the MSDN articles cited) suggest to use volatile. Joe Duffy says volatile is needed on some variants.
In conversations I have been made aware of only one place where optimizations can occur and it is extremely obscure. In general the x86 JIT assumes every non-local to be volatile. the code in question ... public static object SharedVariable { get { if (_sharedVariable == null) { lock (_syncRoot) { if (_sharedVariable == null) { _sharedVariable = new object(); } } } return _sharedVariable; } } _sharedVariable = new object(); should only ever execute once providing the monitor does what it says that it does in the spec and performs a volatile write (and there is only a single write and not intermediary writes) as it also includes a reorderring gaurentee. I think this code is ok in any conforming memory model (the other dependency is stated in 12.6.6 that a reference size write is atomic). Cheers, Greg On 7/9/07, Fabian Schmied <[EMAIL PROTECTED]> wrote:
> This brings us to the interesting point, why is there disagreement? > This is a very clear statement that monitor is indeed a superset of > volatile. Yes, it is. But AFAIK, the problem is that the non-volatile read at the beginning of Ron's code might see the assigned _provider member before the constructor execution (or Activator.CreateInstance) has finished execution (due to reordered writes). Yes, at the end of the lock, it is as if the write had been volatile, but the non-volatile read can see the assignment before the lock is released. This is also why volatile solves the problem - I understand that if _provider is volatile, all out-of-order writes occur befor the assignment is made. It is also why the explicit memory barrier suggested by Stoyan solves the problem. Note that he does the following: I instance = Activator.... Thread.MemoryBarrier(); // so that any out-of-order writes complete[1] provider_ = instance; So he ensures that all out-of-order writes finish before the non-volatile read can see the result. It seems the controversial point is whether such out-of-order writes can occur with the .NET 2.0 memory model. Vance Morrison has written an article [1] where he seems to say no (in this case), so volatile (or explicit memory barrier) are not needed. Other sources (such as the MSDN articles cited) suggest to use volatile. Joe Duffy says volatile is needed on some variants. Fabian [1] http://msdn.microsoft.com/msdnmag/issues/05/10/MemoryModels/ (Technique 4) =================================== This list is hosted by DevelopMentor(r) http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com
-- Studying for the Turing test =================================== This list is hosted by DevelopMentorĀ® http://www.develop.com View archives and manage your subscription(s) at http://discuss.develop.com