diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-09-27 01:39:15 +0000 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-10-24 21:00:36 -0400 |
commit | 2781d68c5d94fd87435d6316c2d4118171e97b14 (patch) | |
tree | b21bb78704eeed08cdeb26d47a2827cc55fc9701 /rts/Capability.c | |
parent | 16b136b0c3c79833a1e35305f9c5d1b0511eda9c (diff) | |
download | haskell-2781d68c5d94fd87435d6316c2d4118171e97b14.tar.gz |
rts: Annotate benign race in waitForCapability
Diffstat (limited to 'rts/Capability.c')
-rw-r--r-- | rts/Capability.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/rts/Capability.c b/rts/Capability.c index 6ab8f40dfa..07141009a1 100644 --- a/rts/Capability.c +++ b/rts/Capability.c @@ -749,6 +749,22 @@ static Capability * waitForReturnCapability (Task *task) #if defined(THREADED_RTS) /* ---------------------------------------------------------------------------- + * capability_is_busy (Capability *cap) + * + * A predicate for determining whether the given Capability is currently running + * a Task. This can be safely called without holding the Capability's lock + * although the result may be inaccurate if it races with the scheduler. + * Consequently there is a TSAN suppression for it. + * + * ------------------------------------------------------------------------- */ +static bool capability_is_busy(const Capability * cap) +{ + TSAN_ANNOTATE_BENIGN_RACE(&cap->running_task, "capability_is_busy"); + return cap->running_task != NULL; +} + + +/* ---------------------------------------------------------------------------- * find_capability_for_task * * Given a Task, identify a reasonable Capability to run it on. We try to @@ -765,7 +781,11 @@ static Capability * find_capability_for_task(const Task * task) } else { // Try last_free_capability first Capability *cap = last_free_capability[task->node]; - if (cap->running_task == NULL) { + + // N.B. There is a data race here since we are loking at + // cap->running_task without taking cap->lock. However, this is + // benign since the result is merely guiding our search heuristic. + if (!capability_is_busy(cap)) { return cap; } else { // The last_free_capability is already busy, search for a free |