[dmd-concurrency] synchronized, shared, and regular methods inside the same class

Andrei Alexandrescu andrei at erdani.com
Mon Jan 4 15:58:54 PST 2010


Sean Kelly wrote:
> On Jan 4, 2010, at 9:00 AM, Andrei Alexandrescu wrote:
>> The only things that work on shared objects are:
>>
>> * calls to synchronized or shared methods, if any;
>>
>> * reading if the object is word-size or less;
>>
>> * writing if the object is word-size or less.
> 
> Cool!  It's perhaps a minor issue right now, but it would be nice if RMW operations could be performed via library functions.  Hopefully all that's required is to accept a "ref shared T" and then write ASM for the machinery from there?  ie. Is there any need for compiler changes to support this?

Yes, that's the plan. In fact I have proposed an even more Draconian 
plan: disallow even direct reads and writes to shared objects. To exact 
them, user code would have to invoke the intrinsics sharedRead and 
sharedWrite. Then it's very clear and easy to identify where barriers 
are inserted, and the semantics of the program is easily definable: the 
program preserves the sequences of calls to sharedRead and sharedWrite.

Consider your example:

shared int x;
...
++x;

The putative user notices that that doesn't work, so she's like, meh, 
I'll do this then:

int y = x;
++y;
x = y;

And the user remains with this impression that the D compiler is a bit 
dumb. Of course that doesn't avoid the race condition though. If the 
user would have to call atomicIncrement(x) that would be clearly an 
improvement, but even this would be an improvement:

int y = sharedRead(x);
++y;
sharedWrite(y, x);

When writing such code the user inevitably hits on the documentation for 
the two intrinsics, which clearly define their guarantees: only the 
sequence of sharedRead and sharedWrite is preserved. At that point, 
inspecting the code and understanding how it works is improved.

> So if I have:
> 
>     class A
>     {
>         void fn() shared { x = 5; }
>         int x;
>     }
> 
> Is this legal?  If the type of the object doesn't change then I'd guess that I won't be allowed to access non-shared fields inside a shared function?

Shared automatically propagates to fields, so typeof((new shared(A)).x) 
is shared int. Of course that's not the case right now; the typeof 
expression doesn't even compile :o).


Andrei


More information about the dmd-concurrency mailing list