summaryrefslogtreecommitdiff
path: root/rts/Schedule.c
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2020-10-22 12:02:58 -0400
committerBen Gamari <ben@smart-cactus.org>2020-10-24 21:00:40 -0400
commit3416244b736b386f0bbf8369083f90110cd524a2 (patch)
tree2fba1c6e5ee086350dab52efd083c11e9ae3c96e /rts/Schedule.c
parentdd175a926c0e9654cd6ac8d9d26b183540c87331 (diff)
downloadhaskell-3416244b736b386f0bbf8369083f90110cd524a2.tar.gz
Capabiliity: Properly fix data race on n_returning_tasks
There is a real data race but can be made safe by using proper atomic (but relaxed) accesses.
Diffstat (limited to 'rts/Schedule.c')
-rw-r--r--rts/Schedule.c9
1 files changed, 7 insertions, 2 deletions
diff --git a/rts/Schedule.c b/rts/Schedule.c
index 20f661ac97..52d89a08fb 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -654,9 +654,14 @@ shouldYieldCapability (Capability *cap, Task *task, bool didGcLast)
// Capability keeps forcing a GC and the other Capabilities make no
// progress at all.
+ // Note [Data race in shouldYieldCapability]
+ // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// We would usually need to hold cap->lock to look at n_returning_tasks but
- // we don't here since this is just an approximate predicate.
- TSAN_ANNOTATE_BENIGN_RACE(&cap->n_returning_tasks, "shouldYieldCapability");
+ // we don't here since this is just an approximate predicate. We
+ // consequently need to use atomic accesses whenever touching
+ // n_returning_tasks. However, since this is an approximate predicate we can
+ // use a RELAXED ordering.
+
return ((RELAXED_LOAD(&pending_sync) && !didGcLast) ||
RELAXED_LOAD(&cap->n_returning_tasks) != 0 ||
(!emptyRunQueue(cap) && (task->incall->tso == NULL