X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=rts%2FTimer.c;h=02d106fde9a2553f2f2fa10930df0f0869170921;hp=0e0b5386b759530934ca135c98d6148a3e51cb56;hb=HEAD;hpb=e1ddf51abb3a89392cc9da9a36b74f0d69f9a36b diff --git a/rts/Timer.c b/rts/Timer.c index 0e0b538..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" @@ -47,7 +48,7 @@ handle_tick(int unused STG_UNUSED) 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 */ } } @@ -64,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: @@ -81,17 +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 +initTimer(void) +{ + initProfTimer(); + if (RtsFlags.MiscFlags.tickInterval != 0) { + initTicker(RtsFlags.MiscFlags.tickInterval, handle_tick); + } + timer_disabled = 1; +} + void startTimer(void) { - initProfTimer(); - if (RtsFlags.MiscFlags.tickInterval != 0) { - startTicker(RtsFlags.MiscFlags.tickInterval, handle_tick); - } + 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); + } }