summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-09-27 18:52:15 +0000
committerMoritz Angermann <moritz.angermann@gmail.com>2020-09-18 07:34:13 +0000
commit64af5c97bb92b91abe6a63f1879b09673edd6b78 (patch)
tree56b4d4e0548319f06305b9fb8fffaf7bca675678
parentb83f7dd8962dce9cddd090b80fcefa5352a5a688 (diff)
downloadhaskell-64af5c97bb92b91abe6a63f1879b09673edd6b78.tar.gz
rts: Eliminate data races on pending_sync
-rw-r--r--rts/Capability.c4
-rw-r--r--rts/Schedule.c2
2 files changed, 3 insertions, 3 deletions
diff --git a/rts/Capability.c b/rts/Capability.c
index 289d2f7705..3168dff2e5 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -538,7 +538,7 @@ releaseCapability_ (Capability* cap,
// be currently in waitForCapability() waiting for this
// capability, in which case simply setting it as free would not
// wake up the waiting task.
- PendingSync *sync = pending_sync;
+ PendingSync *sync = SEQ_CST_LOAD(&pending_sync);
if (sync && (sync->type != SYNC_GC_PAR || sync->idle[cap->no])) {
debugTrace(DEBUG_sched, "sync pending, freeing capability %d", cap->no);
return;
@@ -895,7 +895,7 @@ yieldCapability (Capability** pCap, Task *task, bool gcAllowed)
if (gcAllowed)
{
- PendingSync *sync = pending_sync;
+ PendingSync *sync = SEQ_CST_LOAD(&pending_sync);
if (sync && sync->type == SYNC_GC_PAR) {
if (! sync->idle[cap->no]) {
diff --git a/rts/Schedule.c b/rts/Schedule.c
index c8877f8c04..4f8b67ceb8 100644
--- a/rts/Schedule.c
+++ b/rts/Schedule.c
@@ -637,7 +637,7 @@ shouldYieldCapability (Capability *cap, Task *task, bool didGcLast)
// 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 (right?).
TSAN_ANNOTATE_BENIGN_RACE(&cap->n_returning_tasks, "shouldYieldCapability");
- return ((pending_sync && !didGcLast) ||
+ return ((RELAXED_LOAD(&pending_sync) && !didGcLast) ||
cap->n_returning_tasks != 0 ||
(!emptyRunQueue(cap) && (task->incall->tso == NULL
? peekRunQueue(cap)->bound != NULL