I want to add a Phobos module with template mixins for common idioms.

Idan Arye GenericNPC at gmail.com
Mon May 20 08:28:55 PDT 2013


On Monday, 20 May 2013 at 11:19:44 UTC, Diggory wrote:
> Of course it's possible, for example the code may produce the 
> expected result if some invariant holds which does in fact hold 
> if there was a single thread running, but with multiple threads 
> the invariant is broken. Or more simply - the fact remains that 
> you are writing on one thread (correctly using synchronisation) 
> and reading from another (not using synchronisation) and 
> synchronisation is required on both the read and the write. The 
> compiler/CPU is then free to reorder the reads under the 
> assumption that the value won't change, and this assumption is 
> clearly wrong.

I do not assume that the compiler or the CPU will not change the 
order of reads in the unsynchronized thread - I showed that the 
result of `hasInstance()` is not affected by such reordering! 
`hasInstance()` has a single read to __gshared memory, and the 
only thing that can effect the result of that read is a write to 
that memory, which is done *once* in the synchronized thread. 
That means I should only care when the read in `hasInstance()` 
happens related to that write.

I have shown that whether the read happens before the write, or 
the write happens before the read, or they happen at the same 
time, or the write is split and the read is done between the two 
parts of the write, or the other way around, or if both the read 
and write are split and their parts are performed alternately - 
no matter what, `hasInstance()` yields a result I can rely on.

Since `hasInstance()` produces reliable results even if it gets 
mixed in the timeframe of the instantiation in another thread - I 
see no reason to do a costly synchronization to prevent the 
mixing.



I have tried to form a similar proof for the static branch in 
`instance()` that handles the no-default-constructor case, and 
realized that this one does need synchronization, because the 
compiler might decide to set the reference before it runs the 
initialization of the object. Even though the result it will 
return will be the correct reference to the instance, the 
instance object itself might not be ready.

So, I'm making that part synchronized, simply to force 
`instance()` to wait until the instance object has finished it's 
instantiation.


More information about the Digitalmars-d mailing list