[Gc] Using the Boehm-Demers-Weiser GC with a new threading library
Stephane.Epardaud at sophia.inria.fr
Mon May 2 07:12:00 PDT 2005
I am developing a threading library, and wish to make it work with your GC. As I
understand this may very well not be trivial, and by no means would I ask you to
work on this task, I thought at least I could ask you for some information as to
how I should proceed.
I have two aspects in my threading library:
- The first one is cooperative threads, implemented in C via copying of the
stack, and setjmp/longjmp. Every new thread saves its stack and setjmp result in
the heap before cooperating to another thread by restoring its stack and doing a
longjmp. If I'm not clear here, I can probably explain better, but I'm sure this
is rather common.
- The second one is that I want my threads to be able to become asynchronous,
and this is done in a rather complicated way involving pthreads. Every thread
starts as cooperative. If I want a thread that can become asynchronous, I have
to specify it when I create it. If this is the case, then I have to create a
pthread in order to get a new stack (this is where it really differs from GNU
PTH). This is where it gets fishy. The new pthread will do nothing and wait on a
condition variable. Then the main thread (the one which was doing stack copies
and setjmp, scheduling cooperative threads) schedules that new thread by doing a
longjmp back and forth from it, just like "plain" cooperative threads. If that
threads wishes to become asynchronous, it saves its stack, jumps to the next
cooperative thread (the main thread), which then wakes up the PThread, which in
turn will restore the saved stack and longjump to where it was when it was
cooperative. Still there?
If I try to rephrase this: I'm using pthreads for creating a stack. My main
thread jumps back and forth from/to any thread/pthread's stack. And if a thread
wants to become asynchronous, we save it, restore the stack which was doing a
pthread_cond_wait, wake it up, and let it jump to where we saved it.
This is rather complex, and perhaps suboptimal compared to executing pthreads
cooperatively using mutexes until asynchronousness was needed, and definitely
hard to port.
Anyways, this is using linux on x86 and pthreads (NPTL it seems) and I think I
have a quite simple list of places to treat as roots, such as:
- The main stack (this is already done by the GC), which contains the currently
active cooperative stack.
- The other saved cooperative stacks (this is saved in memory which is
GC_malloc'ed so it should already be done, but with a limit in where I look,
since I do not shrink them, and so there's always a bit of dead stack at the
end, which should not be looked at), except for the saved stack of the currently
running thread, of course, which is dead stack.
- The bits of stacks from PThreads which are suspended in pthread_cond_wait
(again this is saved in an area alloc'ed with GC_malloc, so it should work)
- And for pthreads which have been made asynchronous, the normal pthread stack I
guess (though the normal pthread stack has to be scanned anyways, even if the
pthread is cooperative and its stack used by the main thread, so it should be
I've looked a bit at the linux_threads.c file in your GC, and it looks very
clear and documented. The only thing it seems I would have to do in the end is
to restrict the GC scanning of parts of some GC_malloc'ed blocks. But maybe I'm
completely missing something ?
In any case, do you have any advice in how to restrict such scanning (pointers
to code that does it, perhaps other projects needed doing that already, or where
a good place would be to put it), or any thing I should know about messing about
with the GC ?
Again, I do not mean to ask you for too much time, nor for any code, just any
advice on whether what I just said made any sense, if it looks like doable or
just plain stupid, words of wisdom perhaps :)
Thanks a lot.
More information about the Gc