www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - GC and threads

reply "Saaa" <empty needmail.com> writes:
Will a garbage collection sweep halt all threads momentarily?
If so, isn't there a way around this? 
Jan 28 2007
next sibling parent reply "Saaa" <empty needmail.com> writes:
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.
Jan 28 2007
parent reply "Saaa" <empty needmail.com> writes:
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.

 

Jan 28 2007
parent Sean Kelly <sean f4.ca> writes:
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
Jan 28 2007
prev sibling next sibling parent reply Frits van Bommel <fvbommel REMwOVExCAPSs.nl> writes:
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.
Jan 28 2007
parent "Saaa" <empty needmail.com> writes:
 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 :)
Jan 28 2007
prev sibling parent Sean Kelly <sean f4.ca> writes:
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
Jan 28 2007