[dmd-concurrency] draft 7

Robert Jacques sandford at jhu.edu
Mon Feb 1 14:00:50 PST 2010


On Mon, 01 Feb 2010 16:49:27 -0500, Andrei Alexandrescu  
<andrei at erdani.com> wrote:
> Michel Fortin wrote:
>> Le 2010-02-01 à 15:30, Andrei Alexandrescu a écrit :
>>
>>> Michel Fortin wrote:
>>>>> The program would compile successfully with the following
>>>>> changes to nyukNyuk and sneaky: shared(double)* nyukNyuk; //
>>>>> or: shared(double*) nyukNyuk; void sneaky(ref shared(double) r)
>>>>> { nyukNyuk = &r; }
>>>> How can that be safe? Leaking the reference, even as 'shared',  
>>>> doesn't prevent someone from accessing the variable without
>>>> acquiring the lock. Are you suggesting that mixing atomic
>>>> operations and mutex synchronization for the same variable is
>>>> okay? Because it's not.
>>> You are making a good point. I thought of banning escapes
>>> altogether. After all, if someone has access to a shared data
>>> member and the synchronized method assumes it can temporarily
>>> optimize access to that member as if it's unshared, things can get
>>> messed up.
>>>  On the other hand, if you hand out a reference to a member, you're
>>> kind of setting yourself up for surprises. Far as the type system
>>> is concerned, it's doing the right thing.
>> Escaping a value, even as 'shared', breaks the synchronization
>> guaranties. If the type system cares about synchronization, then it
>> should not allow a variable to escape.
>
> OK, then all escaping from synchronized methods is out. I'm 80%  
> convinced myself. Does everybody agree?
>
>>> One related thought: a long time ago, Walter, Bartosz and I briefly
>>> coquetted with the idea of using "scope" to denote an unescaping
>>> parameter:
>>>  void print(scope int[] array) { ... }
>>>  With this signature print guarantees it won't escape anything in
>>> array. Then synchronized functions can pass (addresses of) members
>>> to functions like print.
>>  That's a simple solution. It's limited, since you can't implement
>> something like swap(ref int[], ref int[]) and thus not sorting
>> algorithm, but it's better than nothing.
>
> I think swap could be typed as:
>
> swap(scope ref int[], scope ref int[]);
>
> The point of scope parameter typechecking is that swap does not save a  
> reference surreptitiously; I think escaping to another scope parameter  
> should be fine (if somewhat conservative).

Scope needs to prevent escaping to any scope, which most importantly  
includes other scope variables. i.e.:

shared int[] x;
int[] y;
swap(x,y);

Causes a unshared array to become shared.

Generally, you'd want something like scope constraints or scope tags to do  
something like swap. But this can be better down using templates and  
template constraints today. Also, when you think in terms of 'lent'  
swapping two borrowed items and returning different items to the original  
owners is completely illogical.

> In fact I've had this idea for a while now that "ref" should imply "I  
> won't escape it". That would make ref strictly pass-down. Walter is  
> mildly favorable to that idea. I think it's worth giving it a closer  
> look now.

This sounds like an okay idea, but I haven't thought through all the  
implications yet.



More information about the dmd-concurrency mailing list