[gclist] Boehm GC & threads on Linux

David Chase chase@world.std.com
Thu, 17 Feb 2000 13:23:05 -0500


At 03:49 AM 2/18/00 +1100, Fergus Henderson wrote:
>When compiled in "thread-safe" mode,
>the Mercury runtime allocates a big structure (that it uses that to
>hold some of our virtual machine registers, pointers to the Mercury
>stacks, etc.) on the GC'd heap, and puts a pointer to that structure
>in thread-local storage.

As I understand the usual implementations of thread local storage,
that memory is not going to get traced.  The thread runtime has
probably used malloc to allocate a per-thread vector of pointers
to stuff, stuffed a pointer to that vector in some Secret Place,
and that vector is not going to get traced.

I figure that modifying Linux is not an option, and modifying
the collector in a way that it depends on internal Linux data
stuctures is not a long-term good solution.  Plan C is to modify
your thread-starting code so that it contains something along the
following lines:

  typedef void * voidstar;
  static void inhibit_tail_call_proc(voidstar x) {}
  void (*inhibit_tail_call)(voidstar) = inhibit_tail_call_proc;
  

  mercury_thread_start(void * parameters) {
     volatile voidstar duplicate_of_tsd = gc_malloc (big_enough_for_data);
     pthread_setspecific(key, duplicate_of_tsd);
     ...
     /* run thread */
     ...
     inhibit_tail_call(duplicate_of_tsd);
  }

The name of the game here is to be sure that the stack contains
a copy of the same pointer you stuffed into the thread-specific-data.
That will prevent collection of the TSD, without you needing to know
the gory details.

>If you have any hints on how to debug this kind of thing,
>they'd be much appreciated.  Thanks.

It's always a little hard to figure out where you didn't
do the thing that you were supposed to be doing.

David Chase
chase@naturalbridge.com
http;//www.naturalbridge.com