diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-12-01 14:11:11 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-10-24 21:00:36 -0400 |
commit | 6517a2ea285688907e8d71e8313f04e919a24445 (patch) | |
tree | 25f3a5bb82fbd62fe3cffba15fdd917a907b6b7a /rts/Schedule.c | |
parent | 31fa87ecb4ff1abc761d776d48e87cd0fd37bedd (diff) | |
download | haskell-6517a2ea285688907e8d71e8313f04e919a24445.tar.gz |
rts: Mitigate races in capability interruption logic
Diffstat (limited to 'rts/Schedule.c')
-rw-r--r-- | rts/Schedule.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/rts/Schedule.c b/rts/Schedule.c index 8af5a51d51..3796ae63de 100644 --- a/rts/Schedule.c +++ b/rts/Schedule.c @@ -405,7 +405,7 @@ schedule (Capability *initialCapability, Task *task) */ if (RtsFlags.ConcFlags.ctxtSwitchTicks == 0 && !emptyThreadQueues(cap)) { - cap->context_switch = 1; + RELAXED_STORE(&cap->context_switch, 1); } run_thread: @@ -432,7 +432,7 @@ run_thread: #endif // reset the interrupt flag before running Haskell code - cap->interrupt = 0; + RELAXED_STORE(&cap->interrupt, false); cap->in_haskell = true; cap->idle = 0; @@ -1132,12 +1132,12 @@ schedulePostRunThread (Capability *cap, StgTSO *t) static bool scheduleHandleHeapOverflow( Capability *cap, StgTSO *t ) { - if (cap->r.rHpLim == NULL || cap->context_switch) { + if (cap->r.rHpLim == NULL || RELAXED_LOAD(&cap->context_switch)) { // Sometimes we miss a context switch, e.g. when calling // primitives in a tight loop, MAYBE_GC() doesn't check the // context switch flag, and we end up waiting for a GC. // See #1984, and concurrent/should_run/1984 - cap->context_switch = 0; + RELAXED_STORE(&cap->context_switch, 0); appendToRunQueue(cap,t); } else { pushOnRunQueue(cap,t); @@ -1238,8 +1238,8 @@ scheduleHandleYield( Capability *cap, StgTSO *t, uint32_t prev_what_next ) // the CPU because the tick always arrives during GC). This way // penalises threads that do a lot of allocation, but that seems // better than the alternative. - if (cap->context_switch != 0) { - cap->context_switch = 0; + if (RELAXED_LOAD(&cap->context_switch) != 0) { + RELAXED_STORE(&cap->context_switch, 0); appendToRunQueue(cap,t); } else { pushOnRunQueue(cap,t); |