Hi!

I'm puzzled with what's the difference between shared and __gshared. Until now I've (mistakenly) considered that shared variables are free from low-level data races. I.e. the operations with shared data are atomic. And that __gshared is the "usual" (in C++ sense) shared data.

So, in my understanding, it was that if I do

shared int s = 0;
void inc()
{
    s++;
}
void main()
{
    foreach (i; iota(100_000).parallel)
        s++;
}

I will always get s == 100_000 by the end of foreach loop. And if I use __gshared specifier, I will get the undefined value less or equal 100_000.

But now I've run the test and I get the "undefined value" result for both shared and __gshared.

I've looked this up in TDPL, and careful reading got me that shared guarantees only that the result of a write is instantly visible to all threads. So according to this, I can load the value in register, change it there, wait until someone else rewrites the value, and put my version on top, discarding someone else's result.

Is this how shared is supposed to work? If so, how is the __gshared different from it? Does it not guarantee that the result of a write is instantly visible to all threads? If so, does this difference really matter?

Reply via email to