diff options
author | Simon Marlow <marlowsd@gmail.com> | 2010-05-18 11:32:14 +0000 |
---|---|---|
committer | Simon Marlow <marlowsd@gmail.com> | 2010-05-18 11:32:14 +0000 |
commit | f9b4bc220a684a970a58dafa9e57d665d29b4121 (patch) | |
tree | a43e79257e8a0b159e47821b202af26c04b8b8e3 /rts/Timer.c | |
parent | 8e4fd5b3be763fc960db16deddd4efc381b815df (diff) | |
download | haskell-f9b4bc220a684a970a58dafa9e57d665d29b4121.tar.gz |
Fix #4074 (I hope).
1. allow multiple threads to call startTimer()/stopTimer() pairs
2. disable the timer around fork() in forkProcess()
A corresponding change to the process package is required.
Diffstat (limited to 'rts/Timer.c')
-rw-r--r-- | rts/Timer.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/rts/Timer.c b/rts/Timer.c index dddc75414d..02d106fde9 100644 --- a/rts/Timer.c +++ b/rts/Timer.c @@ -86,6 +86,15 @@ 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) { @@ -93,21 +102,26 @@ initTimer(void) if (RtsFlags.MiscFlags.tickInterval != 0) { initTicker(RtsFlags.MiscFlags.tickInterval, handle_tick); } + timer_disabled = 1; } void startTimer(void) { - if (RtsFlags.MiscFlags.tickInterval != 0) { - startTicker(); + if (atomic_dec(&timer_disabled) == 0) { + if (RtsFlags.MiscFlags.tickInterval != 0) { + startTicker(); + } } } void stopTimer(void) { - if (RtsFlags.MiscFlags.tickInterval != 0) { - stopTicker(); + if (atomic_inc(&timer_disabled) == 1) { + if (RtsFlags.MiscFlags.tickInterval != 0) { + stopTicker(); + } } } |