diff options
author | GHC GitLab CI <ghc-ci@gitlab-haskell.org> | 2020-09-18 13:19:34 +0000 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-11-08 09:41:41 -0500 |
commit | 40d7aa8a876a70888084d6a412a25860c4d813ac (patch) | |
tree | 46a9177ea02f9583224fedeebdfc0cf21a748c21 | |
parent | 26e8e67092ed26d7cb3c4b1705f5ee6608c484d3 (diff) | |
download | haskell-40d7aa8a876a70888084d6a412a25860c4d813ac.tar.gz |
rts: Fix race in GC CPU time accounting
Ensure that the GC leader synchronizes with workers before calling
stat_endGC.
-rw-r--r-- | rts/sm/GC.c | 9 |
1 files changed, 6 insertions, 3 deletions
diff --git a/rts/sm/GC.c b/rts/sm/GC.c index 5e1975076e..d80c0e94c6 100644 --- a/rts/sm/GC.c +++ b/rts/sm/GC.c @@ -1278,10 +1278,13 @@ gcWorkerThread (Capability *cap) // Wait until we're told to continue RELEASE_SPIN_LOCK(&gct->gc_spin); - SEQ_CST_STORE(&gct->wakeup, GC_THREAD_WAITING_TO_CONTINUE); debugTrace(DEBUG_gc, "GC thread %d waiting to continue...", gct->thread_index); stat_endGCWorker (cap, gct); + // This must come *after* stat_endGCWorker since it serves to + // synchronize us with the GC leader, which will later aggregate the + // GC statistics. + SEQ_CST_STORE(&gct->wakeup, GC_THREAD_WAITING_TO_CONTINUE); ACQUIRE_SPIN_LOCK(&gct->mut_spin); debugTrace(DEBUG_gc, "GC thread %d on my way...", gct->thread_index); @@ -1373,10 +1376,10 @@ wakeup_gc_threads (uint32_t me USED_IF_THREADS, if (i == me || idle_cap[i]) continue; inc_running(); debugTrace(DEBUG_gc, "waking up gc thread %d", i); - if (RELAXED_LOAD(&gc_threads[i]->wakeup) != GC_THREAD_STANDING_BY) + if (SEQ_CST_LOAD(&gc_threads[i]->wakeup) != GC_THREAD_STANDING_BY) barf("wakeup_gc_threads"); - RELAXED_STORE(&gc_threads[i]->wakeup, GC_THREAD_RUNNING); + SEQ_CST_STORE(&gc_threads[i]->wakeup, GC_THREAD_RUNNING); ACQUIRE_SPIN_LOCK(&gc_threads[i]->mut_spin); RELEASE_SPIN_LOCK(&gc_threads[i]->gc_spin); } |