[dmd-concurrency] draft 8: the final countdown

Andrei Alexandrescu andrei at erdani.com
Wed Feb 10 11:08:47 PST 2010


Michel Fortin wrote:
> Le 2010-02-10 à 10:05, Andrei Alexandrescu a écrit :
> 
>> I can't believe it's not butter! Draft 8 is the first that
>> completely covers the topics I'd planned. For a good time download:
>> 
> 
> :-)
> 
> I know we already talked about this subject from the last draft, but
> why do we need atomicOp!"+=" at all? Why not bind += to an atomic
> operation directly like we do for read and writes? (I'm not asking
> for the answer to be in the book, I'm just curious about this
> decision.)

I have no strong opinion. I think it doesn't harm to see that the 
operation is atomic, but then it could be all automated. Others, please 
weigh in.

> About synchronized classes:
> 
>> • Array fields declared declared with type T[] receive type
>> shared(T)[], i.e. the head (the slice limits) is not shared and the
>> tail (the contents of the array) remains shared; • Pointer fields
>> declared with type T* receive type shared(T)*, i.e. the head (the
>> pointer itself ) is not shared and the tail (the pointed-to data)
>> remains shared;
> 
> As I and other said before, this is totally unhelpful. When I want
> the referenced to be protected by the lock, assuming it shared will
> allow it to escape which is *not* safe.
> 
> I think it'd be safer to make the referenced value of those fields
> completely inaccessible. That may sound rash, but it's better than to
> assume you can do something that should't be allowed. As usual, you
> can use a cast to bypass the safeties. And if you really want a
> shared(T)[], you can still write it as shared(T)[].

Nonono. What should happen is no escape of *field* addresses because 
those are exposed to races when accessed naively. Synchronized methods 
do NOT assumes that the *indirections* starting from fields are 
locked/protected/non-shared.

If I have a pointer to int as a field:

- inside the sychronized method, the pointer itself is protected by the 
lock and can be considered not shared. Escaping THE ADDRESS OF that 
pointer would create races because it breaks the assumption that only 
the method messes with it

- the int pointed to by that field is STILL considered shared by the 
method AND by the rest of the world so there's never the risk of an 
undue race. The method can escape it all it wants.

>> To tap into cas-based lock-free goodness, use the shared attribute
>> with a class or struct definition:
>> 
>> struct LockFreeStruct { ... } struct LockFreeClass { ... }
> 
> I think your example lacks 2 'shared', 1 'class' and -1 'struct'.

Ew! Thanks.


Andrei


More information about the dmd-concurrency mailing list