On Wednesday, 17 October 2012 at 08:55:55 UTC, Alex Rønne
Petersen wrote:
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
*:
http://xtzgzorex.wordpress.com/2012/10/11/demystifying-garbage-collectors/
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.)
Introduce the "noshared" keyword.