[Gc] Attaching and dettaching existing threads

Boehm, Hans hans_boehm@hp.com
Mon, 13 Oct 2003 11:17:27 -0700

I agree that this needs to be reconsidered, though not for 6.3.

The original model was that notifying the GC of a new thread should be as
transparent as possible.  On win32 with the GC as a separate dynamic library,
it's completely transparent at the moment; all new threads are automatically
attached.  In all other cases we try to intercept all thread creations, usually
with macros include from gc.h.  The intent is that if you define GC_THREADS
and include "gc.h" everywhere, the rest should be automatic on all platforms.

My feeling is that for C/C++ clients, this is usually the right model.  But
its weaknesses are:

1) It's hard to exclude a thread.  You might rarely want to do that to avoid stopping
it during GC.  But this imposes severe constraints on what that thread can do.
In particular, it can't write any pointers to the collected heap, or allocate
memory using the GC_ routines.

2) The current macro-based interception mechanism doesn't actually guarantee that
we intercept all thread creations.  The code that spawns the thread may not be
recompilable.  It's occasionally useful to "attach" the resulting thread after the
fact.  On Linux, this is probably fixable with linker-based interception, at least for
dynamic executables.  I don't know how to fix it for Windows.

3) This model doesn't handle threads that were running before the dynamic library
containing the GC was loaded.  (Actually, I suspect it does in the win32 GC-as-DLL case,
since I would expect the library to be notified of all such threads.  But it works
nowhere else.)

I think my preference would be to stick with the current model of transparently
attaching threads, but to add two more public calls similar to what Tum proposed:

1) GC_watch_thread() - makes sure that the current thread is known to the GC, even if
it was created in a way that couldn't be intercepted.  It
would take a bit of work to ensure that this is a no-op if the thread was already known
to the GC, but I think that's necessary.

2) GC_ignore_thread() - Ensures that the current thread is not known to the GC.
Should be called just before exit by threads that called GC_watch_thread(), or
by threads that may have been automatically watched but don't want to be stopped
during GC.  No-op if it was already unknown.

(I decided during the last win32_threads.c revision that the attach/detach
terminology is not my preferred choice, since it conflicts with the pthreads use
of "detach".)

This diverges from the JNI/.NET model, in that threads are "watched" by default
if you recompile suitably.  But I don't think that's a serious problem, and for
C/C++ clients it makes life a bit easier, and we remain compatible with current

Does this sound right?


> -----Original Message-----
> From: Thong (Tum) Nguyen [mailto:tum@veridicus.com]
> Sent: Sunday, October 12, 2003 9:13 PM
> To: gc@napali.hpl.hp.com
> Subject: [Gc] Attaching and dettaching existing threads
> Hi,
> The .NET (CLI) P/Invoke architecture allows native OS threads created
> outside of the runtime to invoke "managed" objects.  This 
> would require the
> GC to be aware of these threads as soon as they enter the runtime.
> There currently doesn't seem to be a standard cross platform way of
> attaching and detaching existing threads to the GC.  This 
> seems trivial to
> implement (for linux & windows anyway) since a lot of the 
> code for this
> already exists but is tucked away.
> How about adding some GC_thread_attach and GC_thread_detach 
> to the public
> API.  Does anyone have any opinions on this issue?  
> All the very best,
> ^Tum
> _______________________________________________
> Gc mailing list
> Gc@linux.hpl.hp.com
> https://linux.hpl.hp.com/cgi-bin/mailman/listinfo/gc