[Gc] Using the Boehm-Demers-Weiser GC with a new threading library

Stephane Epardaud 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 
good already)

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 mailing list