[m-dev.] for review: fix GC bug with asm_fast.gc.par

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Oct 4 14:58:52 AEDT 2000


On 03-Oct-2000, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> For review by Tyson and/or Tom.
> 
> ----------
> 
> Estimated hours taken: 20 (roughly -- including time spent by trd and conway)
> 
> Fix a GC-related bug that broke the asm_fast.gc.par grade on
> some systems.
> 
> runtime/mercury_memory.h:
> runtime/mercury_memory.c:
> 	Add MR_GC_NEW_UNCOLLECTABLE() and MR_GC_malloc_uncollectable(),
> 	which are like MR_GC_NEW() and MR_GC_malloc() except that they
> 	call GC_MALLOC_UNCOLLECTABLE() rather than GC_MALLOC().
> 
> runtime/mercury_engine.c:
> 	Allocate the engine with MR_GC_NEW_UNCOLLECTABLE() rather than
> 	MR_GC_NEW(), so that it is safe to store the only pointer to it
> 	in thread-local storage.

Well, that didn't do any harm, but it didn't actually fix the problem.

I was mislead by comments in boehm_gc/gc.h:

    /* Note also that the collector cannot see thread specific data.        */
    /* Thread specific data should generally consist of pointers to         */
    /* uncollectable objects, which are deallocated using the destructor    */
    /* facility in thr_keycreate.                                           */

Unfortunately that doesn't work, presumably because the collector still
doesn't scan objects allocated with GC_malloc_uncollectable() if they
are not reachable from some GC-visible place.  Objects allocated with
GC_malloc_uncollectable() are not treated as roots.

At this point I got a sense of deja vu...
consulting my mail archives, I found the solution:

 | Message-Id: <3.0.6.32.20000217132305.03661dd0 at pop.std.com>
 | X-Sender: chase at pop.std.com
 | X-Mailer: QUALCOMM Windows Eudora Light Version 3.0.6 (32)
 | Date: Thu, 17 Feb 2000 13:23:05 -0500
 | To: Fergus Henderson <fjh at cs.mu.OZ.AU>, gclist at iecc.com
 | From: David Chase <chase at world.std.com>
 | Subject: Re: [gclist] Boehm GC & threads on Linux
 | In-Reply-To: <20000218034907.A9204 at hg.cs.mu.oz.au>
 | Mime-Version: 1.0
 | Content-Type: text/plain; charset="us-ascii"
 | Status: RO
 | Content-Length: 1798
 | Lines: 48
 | 
 | 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 at naturalbridge.com
 | http;//www.naturalbridge.com
 | 
 | 
 | From majordom-gclist-out-owner-fjh=cs.mu.OZ.AU at iecc.com  Sun Feb 20 10:10:56 2000
 | Message-Id: <140D21516EC2D3119EE700902787664456E689 at hplex1.hpl.hp.com>
 | From: "Boehm, Hans" <hboehm at exch.hpl.hp.com>
 | To: "'David Chase'" <chase at world.std.com>, Fergus Henderson <fjh at cs.mu.OZ.AU>,
 |         gclist at iecc.com
 | Subject: RE: [gclist] Boehm GC & threads on Linux
 | Date: Sat, 19 Feb 2000 15:07:25 -0800
 | Mime-Version: 1.0
 | X-Mailer: Internet Mail Service (5.5.2650.21)
 | Content-Type: text/plain;
 | 	charset="iso-8859-1"
 | Sender: owner-gclist at iecc.com
 | Precedence: bulk
 | Status: RO
 | X-Status: A
 | Content-Length: 2653
 | Lines: 68
 | 
 | Linuxthreads in fact uses a two level tree data structure to store
 | thread specific data.  I think I scan the first, but the second is currently
 | (where current is defined to be the snapshot in my workarea) allocated
 | with calloc, and thus not scanned.  This may have changed fairly recently,
 | I haven't checked.
 | 
 | I would greatly prefer to somehow make this work correctly, more or less
 | transparently, though this probably won't happen real soon.  At a minimum,
 | the collector should #define pthread_setspecific and friends to
 | (semi-)transparently apply David's trick.  I might try to talk Ulrich into
 | exporting a bit more info from linuxthreads.
 | 
 | Hans


-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>  |  of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3        |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list