[dmd-concurrency] is shared going to be a type modifier?
Steve Schveighoffer
schveiguy at yahoo.com
Thu Jan 7 13:57:50 PST 2010
----- Original Message ----
> From: Sean Kelly <sean at invisibleduck.org>
>
> On Jan 7, 2010, at 12:34 PM, Steve Schveighoffer wrote:
>
> > ----- Original Message ----
> >
> >> From: Andrei Alexandrescu
> >> Steve Schveighoffer wrote:
> >>> Despite that, I think I get it. The address to a shared member could
> >>> be passed to other threads, even though the full object is not, is
> >>> that correct?
> >>
> >> Of course, plus the more frequent case is:
> >>
> >> class SList { ... }
> >> struct A { int x; shared SList lst; }
> >
> > This to me is a more normal usage. The data that is shared is really the
> list, not the pointer to the list (but the reference is also shared because of
> the deficiencies of the type syntax).
>
> Won't we be able to do:
>
> struct A { int x; shared(SList) lst; }
currently, const(T) applies to *all* of T, even the reference itself. There is no syntax to apply const only to what T references if T is a class. There was a huge discussion about this in the early days of the current const system.
There is a type called Rebindable(T) in std.typecons which essentially is equivalent to only applying const or immutable to the referenced item. Although last I remember there were some problems with it because it used opDot.
> I'd think it would be pretty common to want a local reference to shared data.
> Then you wouldn't have to pay for the atomic read required if the reference
> itself is shared.
I think more than const, we need something like this for shared.
>
> > To be more specific, the following case is odd to me because you are sharing
> data in the same memory segment as unshared data:
> >
> > struct B
> > {
> > int x;
> > shared int y;
> > }
> >
> > And in fact, declaring a variable of type B in a function puts shared data on
> the stack!
>
> Yeah, a fully shared field inside a non-shared class doesn't sound right. The
> smoke test for me is that I think about whether it would work with per-thread
> GCs. If one thread has a reference to "shared" data that actually lives in
> another thread's heap or stack, there's a dangling reference issue if the thread
> terminates (at least in theory--the heap data could easily be handed off to the
> shared GC instead, but let's pretend this is impossible).
Yeah, allowing this seems to imply that the global heap will have to be scanned for local heap collections:
class C
{
shared(int)* ptr1;
int *ptr2;
}
I assume that marking a single member shared makes C get allocated on the global heap.
If ptr1 points to a global-heap variable, and ptr2 points to a thread-local-heap variable, then you have to scan the global heap in order to collect the memory ptr2 is pointing to.
> > Hm... this brings up an interesting point. If you want to say that a
> reference to a shared class is a thread-local, how do you do that? For
> instance, in your struct A, you are most likely not going to share the actual
> reference lst (i.e. &a.lst), just what lst points to. However, the compiler is
> going to assume you are sharing lst because that's what you declared. So every
> access to lst is going to require special memory barriers (and technically
> wasted cycles). Is there going to be a way around this? With const it was not
> as important because const is a compile-time concept, but now the syntax
> deficiency is creeping into runtime and hurting performance. I.e. are we going
> to get an equivalent "Rebindable" type constructor?
>
> See my example of "shared (Something) p" above. This is consistent with how
> const and such work anyway.
No it is not. If you have const(T) x, you can never rebind x, no matter what type is inside the parens.
-Steve
More information about the dmd-concurrency
mailing list