[Gc] Win32: DLLs and thread registration
hans.boehm at hp.com
Mon Feb 11 17:55:24 PST 2008
> > 3. DllMain tests for parallel_initialized==true
> > when called during DLL_THREAD_DETACH.
> > parallel_initialized, however, is always false
> > unless GC_CreateThread (or equivalent) is called.
> > DLL_THREAD_ATTACH neither calls any of them nor
> > registers the newly attached thread since that
> > only happens, when parallel_initialized is true.
The problem here is clearly a missing initialization in sonme configurations.
GC_init_parallel() is also called from GC_init(), which is called by GC_INIT(). But this call only happens if either THREAD_LOCAL_ALLOC or PARALLEL_MARK is defined. I conjecture that if you call GC_INIT explicitly, and your collector is built with THREAD_LOCAL_ALLOC defined, everything will work correctly. I suspect the real reason nobody noticed is that GC_use_DllMain() isn't all that popular, and the test program unfortunately still calls the GC_ wrappers, which call GC_init_parallel.
I think the correct (though currently completely untested!) fix is to call GC_init_parallel() from the end if GC_use_DllMain().
> Currently I am using a workaround (i.e. ugly hack): at the
> very beginning of my programm I once call GC_CreateThread
> with a dummy thread procedure which immediately exits. Thus
> GC_init_parallel gets called and everything works fine. The
> actual bug is, I think, that GC_register_my_thread doesn't
> call GC_init_parallel.
I think the call should happen from GC_use_DllMain(), since that seems to be precisely the case in which
a) We need GC_init_parallel called even if THREAD_LOCAL_ALLOC is not defined (because it also turns on locking for allocation), and
b) it's currently not getting called
And you can't get into the problem case without calling it at the beginning.
> What's also strange: why does win32_threads.c unconditionally
> make use of parallel marking (without checking whether
> PARALLEL_MARK is #defined)? Perhaps I should try to #define
> it myself. That would make GC_init_inner call
> GC_init_parallel and could solve my problem.
As you discovered, this is a naming problem. GC_init_parallel has little to do with parallel marking. It initializes some thread support stuff, mostly thread-local allocation buffers.
PARALLEL_MARK isn't yet supported on win32, though that's probably just a small matter of programming at this point. We need a bit of code to figure out how many processors there are on the architecture, fork the right number of threads, and possibly fix an atomic_ops issue or two.
Thanks for noticing this.
> I'll try that.
> Gc mailing list
> Gc at linux.hpl.hp.com
More information about the Gc