summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2019-12-01 11:52:33 -0500
committerBen Gamari <ben@smart-cactus.org>2020-03-11 18:45:36 -0400
commit513afdc3f1017513d13c0153e90b4658644d7638 (patch)
treeecc3a98dcab723020555e0cda0e1d55c8e1490c1
parenta953bf00585980667bba2bbd95ef4db3cbd493c2 (diff)
downloadhaskell-513afdc3f1017513d13c0153e90b4658644d7638.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.
-rw-r--r--includes/rts/SpinLock.h10
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 */