digitalmars.D - GC and threads
- Saaa (2/2) Jan 28 2007 Will a garbage collection sweep halt all threads momentarily?
- Saaa (18/18) Jan 28 2007 Interrupt Service Routines
- Saaa (6/26) Jan 28 2007 As I read it, this is a more general solution than only for ISR routines...
- Sean Kelly (6/11) Jan 28 2007 On Windows, you'll want to use _beginthread or _beginthreadex, which are...
- Frits van Bommel (11/13) Jan 28 2007 There is, don't use std.thread to start your thread ;). Be careful
- Saaa (2/15) Jan 28 2007 Yeah, I was searching for it, but couldn't find it... until like a minut...
- Sean Kelly (6/8) Jan 28 2007 An incremental GC doesn't halt threads (some actually do as a last
Will a garbage collection sweep halt all threads momentarily? If so, isn't there a way around this?
Jan 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.
Jan 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.
Jan 28 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
Jan 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.
Jan 28 2007
Saaa wrote:Yeah, I was searching for it, but couldn't find it... until like a minute after my post :)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
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