From: Simon Marlow Date: Wed, 7 Jan 2009 12:06:52 +0000 (+0000) Subject: fix a race where the timer signal could remain turned off, leading to deadlock X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=commitdiff_plain;h=16c651b6d49a99b84821dc47153f0c155430f460 fix a race where the timer signal could remain turned off, leading to deadlock --- diff --git a/rts/Schedule.c b/rts/Schedule.c index 7c453d7..9baf755 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -1599,6 +1599,21 @@ delete_threads_and_gc: heap_census = scheduleNeedHeapProfile(rtsTrue); + if (recent_activity == ACTIVITY_INACTIVE && force_major) + { + // We are doing a GC because the system has been idle for a + // timeslice and we need to check for deadlock. Record the + // fact that we've done a GC and turn off the timer signal; + // it will get re-enabled if we run any threads after the GC. + // + // Note: this is done before GC, because after GC there might + // be threads already running (GarbageCollect() releases the + // GC threads when it completes), so we risk turning off the + // timer signal when it should really be on. + recent_activity = ACTIVITY_DONE_GC; + stopTimer(); + } + #if defined(THREADED_RTS) debugTrace(DEBUG_sched, "doing GC"); // reset waiting_for_gc *before* GC, so that when the GC threads @@ -1640,16 +1655,6 @@ delete_threads_and_gc: balanceSparkPoolsCaps(n_capabilities, capabilities); #endif - if (force_major) - { - // We've just done a major GC and we don't need the timer - // signal turned on any more (#1623). - // NB. do this *before* releasing the Capabilities, to avoid - // deadlocks! - recent_activity = ACTIVITY_DONE_GC; - stopTimer(); - } - #if defined(THREADED_RTS) if (gc_type == PENDING_GC_SEQ) { // release our stash of capabilities.