diff options
author | Ben Gamari <ben@smart-cactus.org> | 2019-12-01 11:52:33 -0500 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2020-10-24 20:59:39 -0400 |
commit | d3890ac737e282a582f0cc9819dedd2a8c363501 (patch) | |
tree | b49a6174d46e183d99633429f1572ad0c53d8e11 /includes | |
parent | b3ce6acaae1b386aeca6649738cf286ad71ed5cd (diff) | |
download | haskell-d3890ac737e282a582f0cc9819dedd2a8c363501.tar.gz |
rts/SpinLock: Move to proper atomics
This is fairly straightforward; we just needed to use relaxed operations
for the PROF_SPIN counters and a release store instead of a write
barrier.
Diffstat (limited to 'includes')
-rw-r--r-- | includes/rts/SpinLock.h | 10 |
1 files changed, 4 insertions, 6 deletions
diff --git a/includes/rts/SpinLock.h b/includes/rts/SpinLock.h index 9f09099e2e..0ac51455dd 100644 --- a/includes/rts/SpinLock.h +++ b/includes/rts/SpinLock.h @@ -46,10 +46,10 @@ INLINE_HEADER void ACQUIRE_SPIN_LOCK(SpinLock * p) for (uint32_t i = 0; i < SPIN_COUNT; i++) { StgWord32 r = cas((StgVolatilePtr)&(p->lock), 1, 0); if (r != 0) return; - IF_PROF_SPIN(p->spin++); + IF_PROF_SPIN(__atomic_fetch_add(&p->spin, 1, __ATOMIC_RELAXED)); busy_wait_nop(); } - IF_PROF_SPIN(p->yield++); + IF_PROF_SPIN(__atomic_fetch_add(&p->yield, 1, __ATOMIC_RELAXED)); yieldThread(); } while (1); } @@ -57,17 +57,15 @@ INLINE_HEADER void ACQUIRE_SPIN_LOCK(SpinLock * p) // release spin lock INLINE_HEADER void RELEASE_SPIN_LOCK(SpinLock * p) { - write_barrier(); - p->lock = 1; + RELEASE_STORE(&p->lock, 1); } // initialise spin lock INLINE_HEADER void initSpinLock(SpinLock * p) { - write_barrier(); - p->lock = 1; IF_PROF_SPIN(p->spin = 0); IF_PROF_SPIN(p->yield = 0); + RELEASE_STORE(&p->lock, 1); } #else /* !THREADED_RTS */ |