GC API: Difference between revisions

2,303 bytes added ,  8 April 2008
(next mtg)
Line 160: Line 160:
add root / remove root
add root / remove root


== Synchronization/concurrency ==
== Multithreading ==
The request model, or something.
Each thread must indicate when it enters/leaves a region of code that touches GC-managed memory (and therefore needs GC to happen only when it's at a safe point) and when it enters/leaves a region of code that doesn't touch GC-managed memory at all (basically one long safe point, where the thread doesn't care if GC happens or not).


'''Open issue:''' This whole area.
For a single-threaded program with only one <code>GCHeap</code>, this just means calling <code>gc_begin_request(heap)</code> at startup and <code>gc_end_request(heap)</code> at shutdown.


('''jorendorff note:''' SpiderMonkey has some pretty awesome hacks in the gc synchronization code, requiring equally awesome hacking in ActionMonkey's branch of MMgcMaybe we could better divide the responsibilitiesDiscuss.)
Features:
 
void '''gc_begin_request'''(GCHeap heap);
 
Enter a request.
 
The calling thread must not be in any active requests on any heap.
 
void '''gc_end_request'''(GCHeap heap);
 
Leave the current request.
 
The calling thread must be in an active request on <code>heap</code>.
 
void '''gc_suspend_request'''(GCHeap heap);
 
Suspend the current request.
 
The calling thread must be in an active request on <code>heap</code>.  That request becomes inactive.
 
The calling thread must later call <code>gc_resume_request</code>.
 
Allocations pointed to by C/C++ local variables in the caller or any of its callers at the time of the call to <code>gc_suspend_request</code> will remain reachable until the matching <code>gc_resume_request</code> call.  (That is, they are temporarily rooted.)
 
void '''gc_resume_request'''(GCHeap heap);
 
Resume a suspended request.
 
The calling thread must not be in an active request on any <code>GCHeap</code>.
 
The most recently suspended inactive request that the calling thread is in on <code>heap</code> becomes active.
 
#define '''GC_FAST_SUSPEND_REQUEST'''(heap) ...
#define '''GC_FAST_RESUME_REQUEST'''(heap) ...
 
These are macros such that anywhere a C/C++ statement would be legal, the idiom
 
GC_FAST_SUSPEND_REQUEST(expr);
...
... (0 or more C/C++ statements)
...
GC_FAST_RESUME_REQUEST(expr);
 
is also legal and expands to a C/C++ statement that behaves like this one:
 
{
    gc_suspend_request(heap);
    ...
    ... (the statements)
    ...
    gc_resume_request(heap);
  }
 
except that
 
* in C++, <code>gc_resume_request</code> must called even if an exception is thrown; and
* the behavior is undefined if the statements contain any identifier starting with <code>_gc_</code>.
 
Note that the call to <code>GC_FAST_SUSPEND_REQUEST</code> must be followed by a matching call to <code>GC_FAST_RESUME_REQUEST</code> in the same C/C++ blockIf these macros are used any other way, the result is undefined.
 
void '''gc_yield_request'''(GCHeap heap);
 
Equivalent to <code>{gc_suspend_request(heap); gc_resume_request(heap);}</code>.


== Tracing ==
== Tracing ==
638

edits