static void init_collected_gen (nat g, nat threads);
static void init_uncollected_gen (nat g, nat threads);
static void init_gc_thread (gc_thread *t);
-static void update_task_list (void);
static void resize_generations (void);
static void resize_nursery (void);
static void start_gc_threads (void);
// The other threads are now stopped. We might recurse back to
// here, but from now on this is the only thread.
- // if any blackholes are alive, make the threads that wait on
- // them alive too.
- if (traverseBlackholeQueue()) {
- inc_running();
- continue;
- }
-
// must be last... invariant is that everything is fully
// scavenged at this point.
if (traverseWeakPtrList()) { // returns rtsTrue if evaced something
shutdown_gc_threads(n_gc_threads, gct->thread_index);
- // Update pointers from the Task list
- update_task_list();
-
// Now see which stable names are still alive.
gcStablePtrTable();
freeChain(gen->large_objects);
gen->large_objects = gen->scavenged_large_objects;
gen->n_large_blocks = gen->n_scavenged_large_blocks;
+ gen->n_new_large_blocks = 0;
ASSERT(countBlocks(gen->large_objects) == gen->n_large_blocks);
}
else // for generations > N
// send exceptions to any threads which were about to die
RELEASE_SM_LOCK;
resurrectThreads(resurrected_threads);
- performPendingThrowTos(exception_threads);
ACQUIRE_SM_LOCK;
// Update the stable pointer hash table.
#endif
gct->no_work++;
+#if defined(THREADED_RTS)
+ yieldThread();
+#endif
return rtsFalse;
}
loop:
- traceEvent(&capabilities[gct->thread_index], EVENT_GC_WORK);
+ traceEventGcWork(&capabilities[gct->thread_index]);
#if defined(THREADED_RTS)
if (n_gc_threads > 1) {
// scavenge_loop() only exits when there's no work to do
r = dec_running();
- traceEvent(&capabilities[gct->thread_index], EVENT_GC_IDLE);
+ traceEventGcIdle(&capabilities[gct->thread_index]);
debugTrace(DEBUG_gc, "%d GC threads still running", r);
// scavenge_loop() to perform any pending work.
}
- traceEvent(&capabilities[gct->thread_index], EVENT_GC_DONE);
+ traceEventGcDone(&capabilities[gct->thread_index]);
}
#if defined(THREADED_RTS)
}
/* ----------------------------------------------------------------------------
- Update the pointers from the task list
-
- These are treated as weak pointers because we want to allow a main
- thread to get a BlockedOnDeadMVar exception in the same way as any
- other thread. Note that the threads should all have been retained
- by GC by virtue of being on the all_threads list, we're just
- updating pointers here.
- ------------------------------------------------------------------------- */
-
-static void
-update_task_list (void)
-{
- Task *task;
- StgTSO *tso;
- for (task = all_tasks; task != NULL; task = task->all_link) {
- if (!task->stopped && task->tso) {
- ASSERT(task->tso->bound == task);
- tso = (StgTSO *) isAlive((StgClosure *)task->tso);
- if (tso == NULL) {
- barf("task %p: main thread %d has been GC'd",
-#ifdef THREADED_RTS
- (void *)task->id,
-#else
- (void *)task,
-#endif
- task->tso->id);
- }
- task->tso = tso;
- }
- }
-}
-
-/* ----------------------------------------------------------------------------
Reset the sizes of the older generations when we do a major
collection.