Shared keyword and the GC?

Alex Rønne Petersen alex at
Wed Oct 17 01:55:54 PDT 2012

On 17-10-2012 10:29, renoX wrote:
> Hello,
> in the discussions thread in the recent blog post which summarized how
> GC works(*), the topic of thread-local GC was further discussed and I
> pointed out that by default global variables in D are thread local but I
> was answered that the types doesn't tell which global variable are
> thread local and which are shared so the GC cannot use this information,
> is-it true?
> It seems like a wasted opportunity..
> BR,
> renoX
> *:

Let's step back for a bit and think about what we want to achieve with 
thread-local garbage collection. The idea is that we look only at a 
single thread's heap (and stack/registers, of course) when doing a 
collection. This means that we can -- theoretically -- stop only one 
thread at a time and only when it needs to be stopped. This is clearly a 
huge win in scalability and raw speed. With a scheme like this, it might 
even be possible to get away with a simple mark-sweep or copying GC per 
thread instead of a complicated generational GC, mainly due to the 
paradigms the isolation model induces.

Rust, as it is today, can do this. Tasks (or threads if you will - 
though they aren't the same thing) are completely isolated. Types that 
can potentially contain pointers into a task's heap cannot be sent to 
other tasks at all. Rust also does not have global variables.

So, let's look at D:

1. We have global variables.
1. Only std.concurrency enforces isolation at a type system level; it's 
not built into the language, so the GC cannot make assumptions.
1. The shared qualifier effectively allows pointers from one thread's 
heap into another's.

It's important to keep in mind that in order for thread-local GC (as 
defined above) to be possible at all, *under no circumstances whatsoever 
must there be a pointer in one thread's heap into another thread's heap, 
ever*. If this happens and you apply the above GC strategy (stop one 
thread at a time and scan only that thread's heap), you're effectively 
dealing with something very similar to the lost object problem on 
concurrent GC.

To clarify with regards to the shared qualifier: It does absolutely 
nothing. It's useless. All it does is slap a pretty "I can be shared 
arbitrarily across threads" label on a type. Even if you have this 
knowledge in the GC, it's not going to help you, because you *still* 
have to deal with the problem that arbitrary pointers can be floating 
around in arbitrary threads.

(And don't even get me started on the lack of clear semantics (and even 
the few semi-agreed-upon but flawed semantics) for shared.)

Alex Rønne Petersen
alex at

More information about the Digitalmars-d mailing list