638
edits
(next mtg) |
(→Synchronization/concurrency: first cut :-P) |
||
Line 160: | Line 160: | ||
add root / remove root | add root / remove root | ||
== | == Multithreading == | ||
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). | |||
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. | |||
(''' | 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++ block. If 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 == |
edits