X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Frts%2FTimer.c;h=5be49a52edd9d8731af3d3feda58b1e0d012eb6a;hb=178c14217eddba162b9d90579580da6bf9e20fe9;hp=1f9db85aad13104c7c2fc78c2507da140ecdabb8;hpb=557947d3f93e11285e36423ddb08d859af60ab47;p=ghc-hetmet.git diff --git a/ghc/rts/Timer.c b/ghc/rts/Timer.c index 1f9db85..5be49a5 100644 --- a/ghc/rts/Timer.c +++ b/ghc/rts/Timer.c @@ -19,8 +19,9 @@ #include "Proftimer.h" #include "Schedule.h" #include "Timer.h" +#include "Capability.h" -#ifndef mingw32_TARGET_OS +#if !defined(mingw32_HOST_OS) #include "Itimer.h" #else #include "win32/Ticker.h" @@ -29,12 +30,18 @@ /* ticks left before next pre-emptive context switch */ static int ticks_to_ctxt_switch = 0; +#if defined(RTS_SUPPORTS_THREADS) +/* idle ticks left before we perform a GC */ +static int ticks_to_gc = 0; +#endif + /* * Function: handle_tick() * * At each occurrence of a tick, the OS timer will invoke * handle_tick(). */ +static void handle_tick(int unused STG_UNUSED) { @@ -46,6 +53,36 @@ handle_tick(int unused STG_UNUSED) if (ticks_to_ctxt_switch <= 0) { ticks_to_ctxt_switch = RtsFlags.ConcFlags.ctxtSwitchTicks; context_switch = 1; /* schedule a context switch */ + +#if defined(RTS_SUPPORTS_THREADS) + /* + * If we've been inactive for idleGCDelayTicks (set by +RTS + * -I), tell the scheduler to wake up and do a GC, to check + * for threads that are deadlocked. + */ + switch (recent_activity) { + case ACTIVITY_YES: + recent_activity = ACTIVITY_MAYBE_NO; + ticks_to_gc = RtsFlags.GcFlags.idleGCDelayTicks; + break; + case ACTIVITY_MAYBE_NO: + if (ticks_to_gc == 0) break; /* 0 ==> no idle GC */ + ticks_to_gc--; + if (ticks_to_gc == 0) { + ticks_to_gc = RtsFlags.GcFlags.idleGCDelayTicks; + recent_activity = ACTIVITY_INACTIVE; + blackholes_need_checking = rtsTrue; + /* hack: re-use the blackholes_need_checking flag */ + threadRunnable(); + /* ToDo: this threadRunnable only works if there's + * another thread (not this one) waiting to be woken up + */ + } + break; + default: + break; + } +#endif } } } @@ -57,7 +94,7 @@ startTimer(nat ms) initProfTimer(); #endif - return startTicker(ms); + return startTicker(ms, handle_tick); } int