diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-11-10 13:29:14 -0500 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2022-12-23 19:09:30 -0500 |
commit | 9d63b160287eb8edfe7ab0b1715f21c1b831bfa5 (patch) | |
tree | 99d6a704dc85bf6b2b568f081b72af91fe7c4e21 | |
parent | 602455c9ae6e5a2746f43b1811bb3c54efb0a6f5 (diff) | |
download | haskell-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.c | 18 |
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 */ |