[phobos] Fwd: Re: Ruling out arbitrary cost copy construction?

Steve Schveighoffer schveiguy at yahoo.com
Mon Nov 1 12:16:22 PDT 2010





----- Original Message ----
> From: Brad Roberts <braddr at puremagic.com>
> To: phobos at puremagic.com
> Sent: Mon, November 1, 2010 1:51:34 PM
> Subject: Re: [phobos] Fwd: Re: Ruling out arbitrary cost copy construction?
> 
> On 11/1/2010 10:39 AM, Michel Fortin wrote:
> > Le 2010-11-01 à 12:30, David  Simcha a écrit :
> > 
> >> Can someone please fill me in?   Despite Michael Fortin's repeated attempts
> >> to explain it, I still  don't understand how the status quo could generate 
a
> >> race condition  under reasonable, real-world scenarios.  As I understand it
> >>  (please correct whatever reasoning is wrong):
> >>
> >> 1.   Incrementing/decrementing a size_t is atomic (i.e. has no  
intermediate
> >> state) on x86 and probably just about any other  arch.  It is not, however,
> >> guaranteed sequentially consistent  unless you use the lock instruction.
> >>
> > 
> >> 2.   Stopping the world to do GC acts as an implicit fence.  If it  didn't,
> >> then GC would be horribly broken.  This means that all  refcount
> >> increments/decrements that happened in the owner thread  should be visible 
>to
> >> the collecting thread upon starting a  collection.
> >>
> >> 3.  You'd need some kind of fence  (explicit or implicit) on terminating GC
> >> anyhow, to make data  structures updated by the GC thread visible to all
> >> threads, thus  making any increment/decrement of the reference count field
> >> done in  the GC thread visible to all threads.
> > 
> > 
> > The current GC  stops other threads only during mark and sweep, it then 
>restarts the other  threads and after that it call destructors. That could be 
>changed, but it'd stop  the world for a little longer.
> > 
> > Is "i++" really atomic when i is  a size_t? I though it was a 
>read-modify-write operation. The read might be  atomic, the write might be 
>atomic, but the whole isn't. And in addition to  atomicity, it needs to be 
>sequentially consistent unless we change the GC to  keep threads frozen while 
>calling the destructors.
> > 
> > One option  to avoid atomic ops would be to make the GC call destructors in 
>the thread that  owns the object, but for that you have to figure out which 
>thread owns what and  postpone destruction until that thread allocates new 
>memory from the GC again.  And this approach won't work for immutable objects 
>anyway: they're implicitly  shared.
> > 
> 
> Not relevant.  In either case the memory is still  referenced so won't be  
>released.

Yes it is.  The item being destroyed is not the refcounted item, but the 
reference to the refcounted item.

For instance, imagine a File member of a class object.  The File's destructor is 
called when the object is destroyed in the GC, so it decrements the ref count in 
the File struct, which could have a race with a thread which has a stack-based 
File struct going out of scope.

I thought the GC does only mark with the world stopped, and then does sweep and 
destructors after restarting the threads?  I somewhat remember the conversation 
that we had on Tango IRC when Sean changed it.  It was introduced to fix a very 
real problem -- if the destructors called some C code that tried to acquire a 
lock that a stopped thread currently held, there would be a deadlock (this was 
happening to someone, which is what prompted the discussion).  I don't think we 
can go back.

-Steve



      


More information about the phobos mailing list