X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FTimer.c;h=02d106fde9a2553f2f2fa10930df0f0869170921;hp=493fe3d35f9c697dab5a107b06446eaadd70f57c;hb=cd47700887365ca2a6af17d03e731efce65cf2ac;hpb=e30aca19def5c629a8429bd57e56535b7f8f85c8 diff --git a/rts/Timer.c b/rts/Timer.c index 493fe3d..02d106f 100644 --- a/rts/Timer.c +++ b/rts/Timer.c @@ -14,12 +14,13 @@ * on platform-specific services to install and run the timers. * */ + +#include "PosixSource.h" #include "Rts.h" -#include "RtsFlags.h" + +#include "Timer.h" #include "Proftimer.h" -#include "Storage.h" #include "Schedule.h" -#include "Timer.h" #include "Ticker.h" #include "Capability.h" #include "RtsSignals.h" @@ -42,14 +43,12 @@ static void handle_tick(int unused STG_UNUSED) { -#ifdef PROFILING handleProfTick(); -#endif if (RtsFlags.ConcFlags.ctxtSwitchTicks > 0) { ticks_to_ctxt_switch--; if (ticks_to_ctxt_switch <= 0) { ticks_to_ctxt_switch = RtsFlags.ConcFlags.ctxtSwitchTicks; - context_switch = 1; /* schedule a context switch */ + setContextSwitches(); /* schedule a context switch */ } } @@ -66,15 +65,19 @@ handle_tick(int unused STG_UNUSED) RtsFlags.MiscFlags.tickInterval; 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.idleGCDelayTime / - RtsFlags.MiscFlags.tickInterval; - recent_activity = ACTIVITY_INACTIVE; - blackholes_need_checking = rtsTrue; - /* hack: re-use the blackholes_need_checking flag */ - wakeUpRts(); + /* 0 ==> no idle GC */ + recent_activity = ACTIVITY_DONE_GC; + // disable timer signals (see #1623) + stopTimer(); + } else { + ticks_to_gc--; + if (ticks_to_gc == 0) { + ticks_to_gc = RtsFlags.GcFlags.idleGCDelayTime / + RtsFlags.MiscFlags.tickInterval; + recent_activity = ACTIVITY_INACTIVE; + wakeUpRts(); + } } break; default: @@ -83,18 +86,49 @@ handle_tick(int unused STG_UNUSED) #endif } +// This global counter is used to allow multiple threads to stop the +// timer temporarily with a stopTimer()/startTimer() pair. If +// timer_enabled == 0 timer is enabled +// timer_disabled == N, N > 0 timer is disabled by N threads +// When timer_enabled makes a transition to 0, we enable the timer, +// and when it makes a transition to non-0 we disable it. + +static StgWord timer_disabled; + void -startTimer(void) +initTimer(void) { -#ifdef PROFILING - initProfTimer(); -#endif + initProfTimer(); + if (RtsFlags.MiscFlags.tickInterval != 0) { + initTicker(RtsFlags.MiscFlags.tickInterval, handle_tick); + } + timer_disabled = 1; +} - startTicker(RtsFlags.MiscFlags.tickInterval, handle_tick); +void +startTimer(void) +{ + if (atomic_dec(&timer_disabled) == 0) { + if (RtsFlags.MiscFlags.tickInterval != 0) { + startTicker(); + } + } } void stopTimer(void) { - stopTicker(); + if (atomic_inc(&timer_disabled) == 1) { + if (RtsFlags.MiscFlags.tickInterval != 0) { + stopTicker(); + } + } +} + +void +exitTimer (rtsBool wait) +{ + if (RtsFlags.MiscFlags.tickInterval != 0) { + exitTicker(wait); + } }