shared - i need it to be useful

Walter Bright newshound2 at digitalmars.com
Wed Oct 17 05:40:41 UTC 2018


On 10/15/2018 11:46 AM, Manu wrote:
> [...]

Shared has one incredibly valuable feature - it allows you, the programmer, to 
identify data that can be accessed by multiple threads. There are so many ways 
that data can be shared, the only way to comprehend what is going on is to build 
a wall around shared data.

(The exception to this is immutable data. Immutable data does not need 
synchronization, so there is no need to distinguish between shared and unshared 
immutable data.)

This falls completely apart if shared and unshared data can be aliased. When 
Andrei and I came up with the rules for:

    mutable
    const
    shared
    const shared
    immutable

and which can be implicitly converted to what, so far nobody has found a fault 
in those rules. Timon Gehr has done a good job showing that they still stand 
unbreached.

So, how can mutable data become shared, and vice versa? I've never found a way 
to do that that is proveably safe. Therefore, it's up to the programmer.

If a programmer does the following:

     T* p;
     shared(T)* sp;

     p = cast(T*)sp;           (1)
     sp = cast(shared(T)*) p;  (2)

those casts will be rejected in @safe code. They'll have to be in @trusted or 
@system code. It will be up to the programmer to ensure (via mutexes, locks, 
uniqueness, etc.) that:

     (1) sp is a unique pointer and that ownership of the data is thus 
transferred for the lifetime of p

     (2) p is a unique pointer and that ownership of the data is thus 
transferred for the lifetime of sp

A sensible program should try to minimize the places where there are these 
"gates" through the wall, as those gates will be where you'll be looking when 
threading bugs appear.

Allowing implicit aliasing between shared and unshared data means the entire 
program needs to reviewed for threading bugs, rather than just the shared parts. 
One might as well just not have shared as a language feature at all. D being a 
systems programming language, one can certainly write code that way, just like 
one does with C, and with all of the threading bugs one gets doing that.

----------

Currently, the compiler allows you to read/write shared data without any locks 
or atomics. I.e. the compiler doesn't attempt to insert any synchronization on 
your behalf. Given all the ways synchronization can be done, it just seems 
presumptive and restrictive to impose a particular scheme. It's pretty much left 
up to the user.

Which is why I recommend minimizing the amount of code that actually has to deal 
with shared data.


More information about the Digitalmars-d mailing list