// Now see which stable names are still alive.
gcStablePtrTable();
+#ifdef THREADED_RTS
+ if (n_gc_threads == 1) {
+ for (n = 0; n < n_capabilities; n++) {
+ pruneSparkQueue(&capabilities[n]);
+ }
+ } else {
+ pruneSparkQueue(&capabilities[gct->thread_index]);
+ }
+#endif
+
#ifdef PROFILING
// We call processHeapClosureForDead() on every closure destroyed during
// the current garbage collection, so we invoke LdvCensusForDead().
scavenge_until_all_done();
+#ifdef THREADED_RTS
+ // Now that the whole heap is marked, we discard any sparks that
+ // were found to be unreachable. The main GC thread is currently
+ // marking heap reachable via weak pointers, so it is
+ // non-deterministic whether a spark will be retained if it is
+ // only reachable via weak pointers. To fix this problem would
+ // require another GC barrier, which is too high a price.
+ pruneSparkQueue(cap);
+#endif
+
#ifdef USE_PAPI
// count events in this thread towards the GC totals
papi_thread_stop_gc1_count(gct->papi_events);
void
waitForGcThreads (Capability *cap USED_IF_THREADS)
{
- nat n_threads = RtsFlags.ParFlags.nNodes;
- nat me = cap->no;
+ const nat n_threads = RtsFlags.ParFlags.nNodes;
+ const nat me = cap->no;
nat i, j;
rtsBool retry = rtsTrue;
void
releaseGCThreads (Capability *cap USED_IF_THREADS)
{
- nat n_threads = RtsFlags.ParFlags.nNodes;
- nat me = cap->no;
+ const nat n_threads = RtsFlags.ParFlags.nNodes;
+ const nat me = cap->no;
nat i;
for (i=0; i < n_threads; i++) {
if (i == me) continue;
if (major_gc && RtsFlags.GcFlags.generations > 1) {
nat live, size, min_alloc, words;
- nat max = RtsFlags.GcFlags.maxHeapSize;
- nat gens = RtsFlags.GcFlags.generations;
+ const nat max = RtsFlags.GcFlags.maxHeapSize;
+ const nat gens = RtsFlags.GcFlags.generations;
// live in the oldest generations
if (oldest_gen->live_estimate != 0) {
// Auto-enable compaction when the residency reaches a
// certain percentage of the maximum heap size (default: 30%).
- if (RtsFlags.GcFlags.generations > 1 &&
- (RtsFlags.GcFlags.compact ||
- (max > 0 &&
- oldest_gen->n_blocks >
- (RtsFlags.GcFlags.compactThreshold * max) / 100))) {
+ if (RtsFlags.GcFlags.compact ||
+ (max > 0 &&
+ oldest_gen->n_blocks >
+ (RtsFlags.GcFlags.compactThreshold * max) / 100)) {
oldest_gen->mark = 1;
oldest_gen->compact = 1;
// debugBelch("compaction: on\n", live);
static void
resize_nursery (void)
{
- lnat min_nursery = RtsFlags.GcFlags.minAllocAreaSize * n_capabilities;
+ const lnat min_nursery = RtsFlags.GcFlags.minAllocAreaSize * n_capabilities;
if (RtsFlags.GcFlags.generations == 1)
{ // Two-space collector:
if (RtsFlags.GcFlags.heapSizeSuggestion)
{
long blocks;
- nat needed = calcNeeded(); // approx blocks needed at next GC
+ const nat needed = calcNeeded(); // approx blocks needed at next GC
/* Guess how much will be live in generation 0 step 0 next time.
* A good approximation is obtained by finding the