== Quote from dsimcha ([email protected])'s article
> == Quote from Sean Kelly ([email protected])'s article
> > == Quote from dsimcha ([email protected])'s article
> > > I've been thinking about how to deal with this issue and make TempAlloc 
> > > safe
> > > enough for inclusion in the standard library.  Since it works by 
> > > allocating
> > > large (currently 4 MB) regions from the C heap, and then sub-allocating 
> > > these
> > > regions to its clients, simply scanning these whole chunks is simply not a
> > > reasonable option, as it would lead to way too many false pointers.  
> > > Using the
> > > GC's addRegion/removeRegion interface at every TempAlloc allocation is 
> > > also
> > > not a reasonable option, as this operation requires a lock and would 
> > > negate
> > > any performance gains from using TempAlloc instead of the GC heap.  The 
> > > only
> > > alternative I see is to make the GC aware of TempAlloc at a very low 
> > > level.
> > > I've looked at the GC code and this doesn't look terribly hard to do.  
> > > Using
> > > some bit twiddling tricks, I can do the bookkeeping to determine which
> > > TempAlloc allocated objects should be scanned by the GC w/o any additional
> > > space overhead.
> > The way I'd do this at the druntime level is generate a Thread.Context 
> > struct
> > for each distinct block used by TempAlloc.  It shouldn't be too difficult to
> > create an API to provide this functionality.  I'd have to do something 
> > roughly
> > along these lines anyway to get thread support working for DLLs in Win32.
> Can you elaborate on this idea?  I don't understand it, so I can't comment on
> whether it would work.

The data range of every execution context in druntime is tracked by the GC
via a linked-list of structs that look roughly like this:

struct Context
{
    void*        begin;
    void*        end;
    Context* next;
}

The stack of each kernel thread has one, as does each user thread (Fiber).  
Currently,
this is all internal, but I could expose an API along these lines:

void attachContext( Context* );
void detachContext( Context* );

Each ThreadAlloc range would have its own Context struct which it would attach
on creation and detach upon destruction.  You're still paying for a mutex call
to attach and detach the struct, but the begin and end pointers can be modified
at will, which gets rid of the problem with addRange, etc.

I suppose I could add this to the interface of GC as well, instead of sticking 
yet more
logic in core.thread.

> > > The downside to this is that TempAlloc would be very tightly coupled to
> > > druntime. Furthermore, if Sean and the other druntime maintainers decided 
> > > they
> > > didn't like my patch, my effort will be wasted.  Therefore, I'd like to 
> > > get
> > > some feedback before I bother doing anything.  Do you think that 
> > > TempAlloc is
> > > universally useful enough to belong in the standard library?  If so, do 
> > > you
> > > believe that it is only suitable for inclusion if it can be made safe w/
> > > respect to storing the only reference to GC-allocated objects?  If so, is 
> > > it
> > > worth tightly coupling it to the GC, and should I start working on this 
> > > and
> > > submit a patch to druntime?
> > For any new runtime features, the easiest thing is just to submit a ticket 
> > or
> > to contact me and tell me what you need.  At first blush, I don't see any
> > problem with providing the functions you'd need to make this work.
> > It may eventually make sense to put TempAlloc, or something like it, into
> > core.memory anyway (there's a reason I didn't name that module core.gc).
> > Sean
> It seems like you want to create some kind of more abstract interface to 
> solve the
> more general problem of interfacing stuff with the GC, rather than just
> integrating TempAlloc directly at a low level.  One way this could be done 
> (not
> necessarily the best way, but the best I've thought of so far) is to make it
> possible to register class objects conforming to some specific range 
> interface (an
> explicit runtime interface w/ virtual functions, not an implicit compile-time
> interface, since we care about the ABI here) with the GC.  These objects would
> return a pointer at each iteration, and then the GC would mark whatever was
> pointed to by that pointer.  This would allow me to use some hacks to keep
> TempAlloc efficient, while keeping these hacks well-encapsulated and out of 
> the
> core GC code.

That's basically how the Context stuff works above.

> In TempAlloc's case specifically, every time a new thread's TempAlloc state 
> was
> initialized, it would register one of these objects with the GC.  This object
> would contain the thread's ID internally, and be set to return empty 
> immediately
> if the thread was already dead.  (TempAlloc-allocated data is absolutely NOT 
> meant
> to be shared between threads.)  Otherwise, it would scan through the currently
> allocated elements and provide the GC with the pointers that are located 
> there,
> through the range interface.

Hm... this may be more tricky than I had outlined above.  If I were to do this 
I'd
probably expose it from GC rather than allow access to the existing context
mechanism.  However... I /could/ possibly add an onExit hook for the Thread
object.  I'll have to think about whether that could cause any problems.


Sean

Reply via email to