summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-09-27 18:25:39 +0000
committerBen Gamari <ben@smart-cactus.org>2020-10-24 21:00:37 -0400
commite10dde371229d45bcc864207cfb6e022dde51bf9 (patch)
treec8c63b0bbd65773fa3c262b5e1495a5fcbf782cd
parent2e9ba3f2881a59fde9932929dce7c42cdcfd4432 (diff)
downloadhaskell-e10dde371229d45bcc864207cfb6e022dde51bf9.tar.gz
rts: Use relaxed operations for cap->running_task (TODO)
This shouldn't be necessary since only the owning thread of the capability should be touching this.
-rw-r--r--rts/Capability.c20
-rw-r--r--rts/Task.c2
2 files changed, 12 insertions, 10 deletions
diff --git a/rts/Capability.c b/rts/Capability.c
index 384d93c27e..0eaec444f8 100644
--- a/rts/Capability.c
+++ b/rts/Capability.c
@@ -525,7 +525,7 @@ releaseCapability_ (Capability* cap,
ASSERT_RETURNING_TASKS(cap,task);
ASSERT_LOCK_HELD(&cap->lock);
- cap->running_task = NULL;
+ RELAXED_STORE(&cap->running_task, NULL);
// Check to see whether a worker thread can be given
// the go-ahead to return the result of an external call..
@@ -696,7 +696,7 @@ static Capability * waitForWorkerCapability (Task *task)
cap->n_spare_workers--;
}
- cap->running_task = task;
+ RELAXED_STORE(&cap->running_task, task);
RELEASE_LOCK(&cap->lock);
break;
}
@@ -737,7 +737,7 @@ static Capability * waitForReturnCapability (Task *task)
RELEASE_LOCK(&cap->lock);
continue;
}
- cap->running_task = task;
+ RELAXED_STORE(&cap->running_task, task);
popReturningTask(cap);
RELEASE_LOCK(&cap->lock);
break;
@@ -763,8 +763,7 @@ static Capability * waitForReturnCapability (Task *task)
* ------------------------------------------------------------------------- */
static bool capability_is_busy(const Capability * cap)
{
- TSAN_ANNOTATE_BENIGN_RACE(&cap->running_task, "capability_is_busy");
- return cap->running_task != NULL;
+ return RELAXED_LOAD(&cap->running_task) != NULL;
}
@@ -798,7 +797,7 @@ static Capability * find_capability_for_task(const Task * task)
i += n_numa_nodes) {
// visits all the capabilities on this node, because
// cap[i]->node == i % n_numa_nodes
- if (!capabilities[i]->running_task) {
+ if (!RELAXED_LOAD(&capabilities[i]->running_task)) {
return capabilities[i];
}
}
@@ -848,7 +847,7 @@ void waitForCapability (Capability **pCap, Task *task)
ACQUIRE_LOCK(&cap->lock);
if (!cap->running_task) {
// It's free; just grab it
- cap->running_task = task;
+ RELAXED_STORE(&cap->running_task, task);
RELEASE_LOCK(&cap->lock);
} else {
newReturningTask(cap,task);
@@ -1038,7 +1037,10 @@ bool
tryGrabCapability (Capability *cap, Task *task)
{
int r;
- if (cap->running_task != NULL) return false;
+ // N.B. This is benign as we will check again after taking the lock.
+ TSAN_ANNOTATE_BENIGN_RACE(&cap->running_task, "tryGrabCapability (cap->running_task)");
+ if (RELAXED_LOAD(&cap->running_task) != NULL) return false;
+
r = TRY_ACQUIRE_LOCK(&cap->lock);
if (r != 0) return false;
if (cap->running_task != NULL) {
@@ -1046,7 +1048,7 @@ tryGrabCapability (Capability *cap, Task *task)
return false;
}
task->cap = cap;
- cap->running_task = task;
+ RELAXED_STORE(&cap->running_task, task);
RELEASE_LOCK(&cap->lock);
return true;
}
diff --git a/rts/Task.c b/rts/Task.c
index 11ba5f1581..5fc2331827 100644
--- a/rts/Task.c
+++ b/rts/Task.c
@@ -473,7 +473,7 @@ startWorkerTask (Capability *cap)
// else get in, because the new worker Task has nowhere to go to
// sleep so that it could be woken up again.
ASSERT_LOCK_HELD(&cap->lock);
- cap->running_task = task;
+ RELAXED_STORE(&cap->running_task, task);
// Set the name of the worker thread to the original process name followed by
// ":w", but only if we're on Linux where the program_invocation_short_name