D2 Multithreading Architecture

Robert Jacques sandford at jhu.edu
Wed Apr 29 17:52:50 PDT 2009


On Wed, 29 Apr 2009 11:49:11 -0400, Jason House  
<jason.james.house at gmail.com> wrote:
> Robert Jacques Wrote:
>> Indeed I intend to handle more than that. The simple answer is that you
>> can not assign to a scope variable except at declaration. This is scope
>> rule 2. But this basically prevents output parameters (for exactly the
>> reasons you mentioned). However, I think you are referencing to the
>> section on the relaxation of rule two, which allows limited use of  
>> output
>> parameters. This relaxation works by recognizing that the head of scope
>> variables _must_ exist on the stack. Thus it is safe (with a few
>> exceptions, see scope rule 6) to swap them. However, assigning to  
>> anywhere
>> off the stack could result in the escape you mentioned and hence is
>> illegal:
>> scope Node ln = myLocalNode;
>> scope Node sn = mySharedNode;
>> swap(sn,ln);       // Okay, were are only swapping the local scope
>> references that exist on the stack
>> swap(sn, ln.next); // Error: Cannot take the reference of a scope tail
>
> My gut reaction is that this is too restrictive of a limitation. If  
> someone can't call swap(n.a, n.b) for an arbitrary non-const type n,  
> they will complain.

I understand where you're coming from, but the whole point of having a  
scope type is to be a 'const' for ownership types. Just like const  
represents n may be immutable or mutable, scope represents n may be stack,  
local, shared or mobile. So I was trying to swap two objects of an  
arbitrary non-const type, I was trying to swap two objects of unknown and  
possibly different types (in this case a local and shared object, which is  
logically invalid). Swap is the canonical function that causes an object  
to escape its scope and supporting it at all is an achievement.

By the way, you can call swap(n.a, n.b) for scope n, if n.a and n.b are  
defined as having the same non-scope ownership type in the scope  
interface. for example:

class Node(T) {
     T value;
     Node(T) next;
}

has a scope interface of
{
     T value;
     Node(T) next;
}

and

shared class SL_Node(T) {
     T value;
     Node(T) next;
}

has a scope interface of
{
     T value;
     scope Node(T) next;
}

so

scope a = new Node!int();
scope b = new Node!int();
swap(a.next,b.next); // Okay, a.next and b.next are both of type local  
Node(int)
swap(a,b.next);      // Error, a is of type scope Node(int)

auto c = new shared Node!int();     // error, writter of Node didn't  
declare it multi-thread aware
scope c = new shared SL_Node!int(); // Okay
scope d = new shared SL_Node!int(); // Okay
swap(c.next,d.next);                // Error, c.next and d.next are scope  
tails.

Hmm, need to clarify this on the wiki.

Another example

shared class E_Node(T) {
     atatic if(is(this==shared)) {
         T* value;
     } else {
         T value;
     }
     Node(T) next;
}

has a scope interface of
{
     // notice that value is missing
     scope Node(T) next;
}





More information about the Digitalmars-d mailing list