Thread overview
GC and threads
Jan 28, 2007
Saaa
Jan 28, 2007
Saaa
Jan 28, 2007
Saaa
Jan 29, 2007
Sean Kelly
Jan 28, 2007
Frits van Bommel
Jan 28, 2007
Saaa
Jan 29, 2007
Sean Kelly
January 28, 2007
Will a garbage collection sweep halt all threads momentarily? If so, isn't there a way around this?


January 28, 2007
Interrupt Service Routines
When the garbage collector does a collection pass, it must pause all running
threads in order to scan their stacks and register contents for references
to GC allocated objects. If an ISR (Interrupt Service Routine) thread is
paused, this can break the program.

Therefore, the ISR thread should not be paused. Threads created with the std.thread functions will be paused. But threads created with C's _beginthread() or equivalent won't be, the GC won't know they exist.

For this to work successfully:

  a.. The ISR thread cannot allocate any memory using the GC. This means
that the global new cannot be used. Nor can dynamic arrays be resized, nor
can any elements be added to associative arrays. Any use of the D runtime
library should be examined for any possibility of allocating GC memory - or
better yet, the ISR should not call any D runtime library functions at all.
  b.. The ISR cannot hold the sole reference to any GC allocated memory,
otherwise the GC may free the memory while the ISR is still using it. The
solution is to have one of the paused threads hold a reference to it too, or
store a reference to it in global data.


January 28, 2007
Saaa wrote:
> Will a garbage collection sweep halt all threads momentarily?

All threads created using std.thread, IIRC.

> If so, isn't there a way around this? 

There is, don't use std.thread to start your thread ;). Be careful though: threads the GC doesn't know about should never have the only reference to an object allocated on the GC heap (i.e. allocated using a non-overloaded 'new').
In fact, it theoretically  shouldn't have *any* reference to an object created by the GC, since the GC is allowed to move objects and can only adjust references in the registers of a thread if it knows about the thread. However, the current GC doesn't move objects, so for now that should still be safe.
January 28, 2007
As I read it, this is a more general solution than only for ISR routines.
Any realtime thread should be created this way.
Is there any reason not to use this way of creating a thread which writes to
a global variable?
(Where is the C's _beginthread() reference)

Wouldn't it be easier for a GC-safe thread in Phobos?

>
> Interrupt Service Routines
> When the garbage collector does a collection pass, it must pause all
> running threads in order to scan their stacks and register contents for
> references to GC allocated objects. If an ISR (Interrupt Service Routine)
> thread is paused, this can break the program.
>
> Therefore, the ISR thread should not be paused. Threads created with the std.thread functions will be paused. But threads created with C's _beginthread() or equivalent won't be, the GC won't know they exist.
>
> For this to work successfully:
>
>  a.. The ISR thread cannot allocate any memory using the GC. This means
> that the global new cannot be used. Nor can dynamic arrays be resized, nor
> can any elements be added to associative arrays. Any use of the D runtime
> library should be examined for any possibility of allocating GC memory -
> or better yet, the ISR should not call any D runtime library functions at
> all.
>  b.. The ISR cannot hold the sole reference to any GC allocated memory,
> otherwise the GC may free the memory while the ISR is still using it. The
> solution is to have one of the paused threads hold a reference to it too,
> or store a reference to it in global data.
>
> 


January 28, 2007
> Saaa wrote:
>> Will a garbage collection sweep halt all threads momentarily?
>
> All threads created using std.thread, IIRC.
>
>> If so, isn't there a way around this?
>
> There is, don't use std.thread to start your thread ;). Be careful though:
> threads the GC doesn't know about should never have the only reference to
> an object allocated on the GC heap (i.e. allocated using a non-overloaded
> 'new').
> In fact, it theoretically  shouldn't have *any* reference to an object
> created by the GC, since the GC is allowed to move objects and can only
> adjust references in the registers of a thread if it knows about the
> thread. However, the current GC doesn't move objects, so for now that
> should still be safe.

Yeah, I was searching for it, but couldn't find it... until like a minute after my post :)


January 29, 2007
Saaa wrote:
> Will a garbage collection sweep halt all threads momentarily?

Yes.

> If so, isn't there a way around this? 

An incremental GC doesn't halt threads (some actually do as a last resort), but it requires compiler support to work.  In essence, every time a pointer is changed with an incremental GC, the GC must be notified.


Sean
January 29, 2007
Saaa wrote:
> As I read it, this is a more general solution than only for ISR routines.
> Any realtime thread should be created this way.
> Is there any reason not to use this way of creating a thread which writes to a global variable?
> (Where is the C's _beginthread() reference)

On Windows, you'll want to use _beginthread or _beginthreadex, which are located in process.h or in std.c.windows.windows in Phobos (I think). On Unix you'll want to use pthread_create, which is in pthread.h or in std.c.linux.linux in Phobos (I think).


Sean