summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Gamari <ben@smart-cactus.org>2022-11-10 13:29:14 -0500
committerMarge Bot <ben+marge-bot@smart-cactus.org>2022-12-23 19:09:30 -0500
commit9d63b160287eb8edfe7ab0b1715f21c1b831bfa5 (patch)
tree99d6a704dc85bf6b2b568f081b72af91fe7c4e21
parent602455c9ae6e5a2746f43b1811bb3c54efb0a6f5 (diff)
downloadhaskell-9d63b160287eb8edfe7ab0b1715f21c1b831bfa5.tar.gz
nonmoving: Eliminate race in bump_static_flag
To ensure that we don't race with a mutator entering a new CAF we take the SM mutex before touching static_flag. The other option here would be to instead modify newCAF to use a CAS but the present approach is a bit safer.
-rw-r--r--rts/sm/NonMovingMark.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/rts/sm/NonMovingMark.c b/rts/sm/NonMovingMark.c
index 98aef4ce47..19776afb8c 100644
--- a/rts/sm/NonMovingMark.c
+++ b/rts/sm/NonMovingMark.c
@@ -1187,15 +1187,17 @@ trace_stack (MarkQueue *queue, StgStack *stack)
static bool
bump_static_flag(StgClosure **link_field, StgClosure *q STG_UNUSED)
{
- while (1) {
- StgWord link = (StgWord) *link_field;
- StgWord new = (link & ~STATIC_BITS) | static_flag;
- if ((link & STATIC_BITS) == static_flag)
- return false;
- else if (cas((StgVolatilePtr) link_field, link, new) == link) {
- return true;
- }
+ ACQUIRE_SM_LOCK;
+ bool needs_marking;
+ StgWord link = (StgWord) *link_field;
+ if ((link & STATIC_BITS) == static_flag) {
+ needs_marking = false;
+ } else {
+ *link_field = (StgClosure *) ((link & ~STATIC_BITS) | static_flag);
+ needs_marking = true;
}
+ RELEASE_SM_LOCK;
+ return needs_marking;
}
/* N.B. p0 may be tagged */