Permalink
Browse files

Fix a bug related to threads blocked on blackholes

We weren't making them live early enough, with the result that
finalizable objects referred to only by a thread blocked on a black
hole could be finalized too early (see conc057 test).
  • Loading branch information...
1 parent 0065d5a commit 693342ffbb61e1da4c009059755fa0b9b1396bb8 Simon Marlow committed Apr 7, 2006
Showing with 34 additions and 10 deletions.
  1. +34 −10 rts/GC.c
View
@@ -172,6 +172,7 @@ static void zero_static_object_list ( StgClosure* first_static );
static rtsBool traverse_weak_ptr_list ( void );
static void mark_weak_ptr_list ( StgWeak **list );
+static rtsBool traverse_blackhole_queue ( void );
static StgClosure * eval_thunk_selector ( nat field, StgSelector * p );
@@ -723,6 +724,11 @@ GarbageCollect ( void (*get_roots)(evac_fn), rtsBool force_major_gc )
}
}
+ // if any blackholes are alive, make the threads that wait on
+ // them alive too.
+ if (traverse_blackhole_queue())
+ flag = rtsTrue;
+
if (flag) { goto loop; }
// must be last... invariant is that everything is fully
@@ -1366,16 +1372,6 @@ traverse_weak_ptr_list(void)
;
}
- // Threads blocked on black holes: if the black hole
- // is alive, then the thread is alive too.
- if (tmp == NULL && t->why_blocked == BlockedOnBlackHole) {
- if (isAlive(t->block_info.closure)) {
- t = (StgTSO *)evacuate((StgClosure *)t);
- tmp = t;
- flag = rtsTrue;
- }
- }
-
if (tmp == NULL) {
// not alive (yet): leave this thread on the
// old_all_threads list.
@@ -1433,6 +1429,34 @@ traverse_weak_ptr_list(void)
}
+/* -----------------------------------------------------------------------------
+ The blackhole queue
+
+ Threads on this list behave like weak pointers during the normal
+ phase of garbage collection: if the blackhole is reachable, then
+ the thread is reachable too.
+ -------------------------------------------------------------------------- */
+static rtsBool
+traverse_blackhole_queue (void)
+{
+ StgTSO *prev, *t, *tmp;
+ rtsBool flag;
+
+ flag = rtsFalse;
+ prev = NULL;
+
+ for (t = blackhole_queue; t != END_TSO_QUEUE; prev=t, t = t->link) {
+ if (! (tmp = (StgTSO *)isAlive((StgClosure*)t))) {
+ if (isAlive(t->block_info.closure)) {
+ t = (StgTSO *)evacuate((StgClosure *)t);
+ if (prev) prev->link = t;
+ flag = rtsTrue;
+ }
+ }
+ }
+ return flag;
+}
+
/* -----------------------------------------------------------------------------
After GC, the live weak pointer list may have forwarding pointers
on it, because a weak pointer object was evacuated after being

0 comments on commit 693342f

Please sign in to comment.