Thread GC non "stop-the-world"
Rainer Schuetze via Digitalmars-d
digitalmars-d at puremagic.com
Sun Sep 28 02:00:48 PDT 2014
On 23.09.2014 02:15, Oscar Martin wrote:
> With some/a lot of work and a little help compiler (currently it
> indicates by a flag if a class/structure contains pointers/references to
> other classes/structures, it could increase this support to indicate
> which fields are pointers/references)
https://github.com/rainers/druntime/gcx_precise2
we could implement a
> semi-incremental-generational-copying GC-conservative like:
>
> http://www.hboehm.info/gc/
> or
> http://www.ravenbrook.com/project/mps/
>
> Being incremental, they try to minimize the "stop-the-world" phase. But
> even with an advanced GC, as programs become more complex and use more
> memory, pause time also increases. See for example (I know it's not
> normal case, but in a few years ...)
As others have already mentioned, incremental GCs need read/write
barriers. There is currently resistence to implementing these in the
compiler, the alternative in the library is using page protection, but
this is very coarse.
"semi-incremental-generational-copying" is probably asking to much in
one step ;-)
>
> http://blog.mgm-tp.com/2014/04/controlling-gc-pauses-with-g1-collector
>
> (*) What if:
> - It is forbidden for "__gshared" have references/pointers to objects
> allocated by the GC (if the compiler can help with this prohibition,
> perfect, if not the developer have to know what he is doing)
> - "shared" types are not allocated by the GC (they could be reference
> counted or manually released or ...)
shared objects will eventually contain references to other objects that
you don't want to handle manually (e.g. string). That means you will
have to add the memory range of the shared object to some GC for
scanning. Back to square one...
> - "immutable" types are no longer implicitly "shared"
>
> In short, the memory accessible from multiple threads is not managed by
> the GC.
Is the compiler meant to help via the type system? I don't think this
works as AFAIK the recommended way to work with shared objects is to
cast away shared after synchronizing on some mutex:
class C
{
void doWork() { /*...*/ }
void doSharedWork() shared
{
synchronized(someMutex)
{
C self = cast(C)this;
self.doWork();
}
}
}
Maybe I missed other patterns to use shared (apart from atomics on
primitive types). Are there any?
>
> With these restrictions each thread would have its "I_Allocator", whose
> default implementation would be an
> incremental-generational-semi-conservative-copying GC, with no
> inteference with any of the other program threads (it should be
> responsible only for the memory reserved for that thread). Other
> implementations of "I_Allocator" could be based on Andrei's allocators.
> With "setThreadAllocator" (similar to current gc_setProxy) you could
> switch between the different implementations if you need. Threads with
> critical time requirements could work with an implementation of
> "I_Allocator" not based on the GC. It would be possible simulate scoped
> classes:
>
> {
> setThreadAllocator(I_Allocator_pseudo_stack)
> scope(exit) {
> I_Allocator_pseudo_stack.deleteAll();
> setThreadAllocator(I_Allocator_gc);
> }
> auto obj = MyClass();
> ...
> // Destructor are called and memory released
> }
>
There is a DIP by Walter with similar functionality:
http://wiki.dlang.org/DIP46
More information about the Digitalmars-d
mailing list