Commit f9b4bc22 authored by Simon Marlow's avatar Simon Marlow
Browse files

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.
parent 8e4fd5b3
......@@ -1533,10 +1533,14 @@ forkProcess(HsStablePtr *entry
ACQUIRE_LOCK(&cap->lock);
ACQUIRE_LOCK(&cap->running_task->lock);
stopTimer(); // See #4074
pid = fork();
if (pid) { // parent
startTimer(); // #4074
RELEASE_LOCK(&sched_mutex);
RELEASE_LOCK(&cap->lock);
RELEASE_LOCK(&cap->running_task->lock);
......
......@@ -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();
}
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment