Although I agree with you that there's more to synchronization in .Net than meets the eye (is this correct English btw ?), I don't think there's a problem with the code I posted. Here's why:
1) locks are internally implemented with volatile reads and writes (which makes tons of sense ;-) 2) according to the CLR memory model, reads and writes from the same processor will never cross each other 3) read/write reordening will never cross locks (they're implemented using volatile) 4) all instructions in a sync'ed block of code will run on one thread and hence on one processor QED -- Henkk BTW, the problem you mention is very real and exactly the reason I forked off the 'finding out if we need initialization' to a separate (valuetype) variable. BTW2, the C# volatile keyword is generally too rigid as it will cause *all* reads and writes to the variable to be volatile BTW3, bNeedInit is *not* a class with an implicit conversion operator for bool ;-) ----- Original Message ----- From: "Ian Griffiths" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Sunday, April 28, 2002 12:24 AM Subject: Re: [DOTNET] lock - how expensive is it to call? > "Henk de Koning" wrote: > > > > if (bNeedInit) { > > lock(this) { > > if (bNeedInit) { > > <init stuff> > > bNeedInit = false; > > } > > This is the classic double check lock for lazy initialization strategy. > Unfortunately, according to the strict definition of the .NET memory model, > this doesn't necessarily work - you can run into trouble due to the way that > the CLR allows multiprocessor caching architectures to reorder memory > accesses. > > (It's broken under Java too for more or less exactly the same reasons by the > way.) > > See Vance Morrison's excellent essay on this subject here: > > http://discuss.develop.com/archives/wa.exe?A2=ind0203B&L=DOTNET&P=R375 > > and the correction he posted after he realised it had a typo here: > > http://discuss.develop.com/archives/wa.exe?A2=ind0203B&L=DOTNET&P=R25512 > > > In brief, you will actually get away with the above code on the current CLRs > because Pentiums are relatively conservative about how they order their > memory accesses. But there is the potential for it to be broken. (Who > knows how it will behave on a multi-processor IA64 system, for example?) To > fix it, you need to use a memory barrier operation. Unfortunately the > memory barrier operations aren't directly available in the current release > of .NET - this article implies they will be in some future version. > (However, I believe you can get the same effect as the > System.Threading.Thread.MemoryBarrier(); by reading from and writing to a > volatile variable.) > > > -- > Ian Griffiths > DevelopMentor > > You can read messages from the DOTNET archive, unsubscribe from DOTNET, or > subscribe to other DevelopMentor lists at http://discuss.develop.com. > You can read messages from the DOTNET archive, unsubscribe from DOTNET, or subscribe to other DevelopMentor lists at http://discuss.develop.com.