From 37ad8856fd97dfdbd334e88300ff661f772b8110 Mon Sep 17 00:00:00 2001 From: Sylvain Henry <sylvain@haskus.fr> Date: Wed, 21 Jul 2021 11:18:14 +0200 Subject: [PATCH] RTS: try to fix timer races * Pthread based timer was initialized started while some other parts of the RTS assume it is initialized stopped, e.g. in hs_init_ghc: /* Start the "ticker" and profiling timer but don't start until the * scheduler is up. However, the ticker itself needs to be initialized * before the scheduler to ensure that the ticker mutex is initialized as * moreCapabilities will attempt to acquire it. */ * after a fork, don't start the timer before the IOManager is initialized: the timer handler (handle_tick) might call wakeUpRts to perform an idle GC, which calls wakeupIOManager/ioManagerWakeup Found while debugging #18033/#20132 but I couldn't confirm if it fixes them. (cherry picked from commit 5f3991c7cab8ccc9ab8daeebbfce57afbd9acc33) --- rts/Schedule.c | 5 ++++- rts/posix/itimer/Pthread.c | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/rts/Schedule.c b/rts/Schedule.c index 061de639b28f..204f356554e5 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -2157,7 +2157,6 @@ forkProcess(HsStablePtr *entry // On Unix, all timers are reset in the child, so we need to start // the timer again. initTimer(); - startTimer(); // TODO: need to trace various other things in the child // like startup event, capabilities, process info etc @@ -2167,6 +2166,10 @@ forkProcess(HsStablePtr *entry ioManagerStartCap(&cap); #endif + // start timer after the IOManager is initialized + // (the idle GC may wake up the IOManager) + startTimer(); + // Install toplevel exception handlers, so interruption // signal will be sent to the main thread. // See #12903 diff --git a/rts/posix/itimer/Pthread.c b/rts/posix/itimer/Pthread.c index 73b1eba5def6..738e5ec469cc 100644 --- a/rts/posix/itimer/Pthread.c +++ b/rts/posix/itimer/Pthread.c @@ -168,7 +168,7 @@ void initTicker (Time interval, TickProc handle_tick) { itimer_interval = interval; - stopped = false; + stopped = true; exited = false; #if defined(HAVE_SIGNAL_H) sigset_t mask, omask; -- GitLab