diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-09-27 01:51:39 +0000 |
---|---|---|
committer | Ben Gamari <ben@well-typed.com> | 2020-12-01 12:48:54 -0500 |
commit | 1ada18d287927d78d9dbdba062e2c882177f2d4f (patch) | |
tree | 1d17a49b096f8cf78de0a586ce2afe6fc61bef60 | |
parent | c93f11feeb918c3c62c0af1f7e757943d52f7f8e (diff) | |
download | haskell-1ada18d287927d78d9dbdba062e2c882177f2d4f.tar.gz |
rts: Fix races in Pthread timer backend shudown
We can generally be pretty relaxed in the barriers here since the timer
thread is a loop.
-rw-r--r-- | rts/posix/itimer/Pthread.c | 19 |
1 files changed, 11 insertions, 8 deletions
diff --git a/rts/posix/itimer/Pthread.c b/rts/posix/itimer/Pthread.c index 860dc81cb5..6f86337ff5 100644 --- a/rts/posix/itimer/Pthread.c +++ b/rts/posix/itimer/Pthread.c @@ -84,11 +84,11 @@ static Time itimer_interval = DEFAULT_TICK_INTERVAL; // Should we be firing ticks? // Writers to this must hold the mutex below. -static volatile bool stopped = false; +static bool stopped = false; // should the ticker thread exit? // This can be set without holding the mutex. -static volatile bool exited = true; +static bool exited = true; // Signaled when we want to (re)start the timer static Condition start_cond; @@ -119,7 +119,9 @@ static void *itimer_thread_func(void *_handle_tick) } #endif - while (!exited) { + // Relaxed is sufficient: If we don't see that exited was set in one iteration we will + // see it next time. + while (!RELAXED_LOAD(&exited)) { if (USE_TIMERFD_FOR_ITIMER) { ssize_t r = read(timerfd, &nticks, sizeof(nticks)); if ((r == 0) && (errno == 0)) { @@ -141,7 +143,8 @@ static void *itimer_thread_func(void *_handle_tick) } // first try a cheap test - if (stopped) { + TSAN_ANNOTATE_BENIGN_RACE(&stopped, "itimer_thread_func"); + if (RELAXED_LOAD(&stopped)) { OS_ACQUIRE_LOCK(&mutex); // should we really stop? if (stopped) { @@ -185,7 +188,7 @@ void startTicker(void) { OS_ACQUIRE_LOCK(&mutex); - stopped = 0; + RELAXED_STORE(&stopped, false); signalCondition(&start_cond); OS_RELEASE_LOCK(&mutex); } @@ -195,7 +198,7 @@ void stopTicker(void) { OS_ACQUIRE_LOCK(&mutex); - stopped = 1; + RELAXED_STORE(&stopped, true); OS_RELEASE_LOCK(&mutex); } @@ -203,8 +206,8 @@ stopTicker(void) void exitTicker (bool wait) { - ASSERT(!exited); - exited = true; + ASSERT(!SEQ_CST_LOAD(&exited)); + SEQ_CST_STORE(&exited, true); // ensure that ticker wakes up if stopped startTicker(); |