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