Very limited shared promotion

Timon Gehr timon.gehr at gmx.ch
Wed Jun 19 13:45:58 UTC 2019


On 19.06.19 11:13, Walter Bright wrote:
> 
> Using the resulting value of x:
> 
>    int x;
>    void fun(scope ref shared(int) x) { ... }
>    fun(x); // implicit promotion to shared in this case
>    int y = x; // add this line
> 
> And now there's a problem. The compiler thinks x is thread local, so it 
> doesn't add synchronization to the read of x.

Probably `fun` should be `immutable` or `shared` as well. Otherwise 
there is no way to tell at the call site that it does not also capture 
`x` mutably, in which case the implicit promotion couldn't be allowed.

> Not adding synchronization 
> means that although fun() has terminated all the threads it spawned 
> accessing x, it does not mean the memory caches of x are updated.
> ...

The @trusted code that decided to send the `scope` reference to other 
threads has to make sure that all reads/writes to the `scope`d reference 
context are visible on the current thread before it returns. (Otherwise, 
from the perspective of the current thread, there are still copies of 
the `scope` reference around, even though the function call has 
terminated, which goes against `scope` guarantees.)

> While you may have coded fun() to update the caches of x before 
> returning, the compiler can't know that, and so the compiler cannot 
> allow the implicit conversion.
> ...

The compiler can allow the implicit conversion because in @safe code 
there is no way to send `scope` data to other threads and @trusted code 
has to respect `scope` guarantees.

> In other words, adding `scope` does not guarantee SC-DRF (Sequential 
> Consistency - Data Race Free).

I think it does. The challenge is to ensure that the implicit promotion 
to `shared` doesn't result in `shared`/unshared aliasing. I don't think 
there is a problem with implicitly casting back to unshared, as the 
called function promises not to leak the references.


More information about the Digitalmars-d mailing list