From c63f37858041ffd2bcf751f57632c90d630eddc2 Mon Sep 17 00:00:00 2001 From: Vorapol Rinsatitnon Date: Thu, 18 Sep 2025 12:01:09 +0800 Subject: [PATCH] Replace atomic Or with compare-and-swap loop --- src/sync/waitgroup.go | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/sync/waitgroup.go b/src/sync/waitgroup.go index 5b035aa3..8aeae7bf 100644 --- a/src/sync/waitgroup.go +++ b/src/sync/waitgroup.go @@ -94,10 +94,19 @@ func (wg *WaitGroup) Add(delta int) { fatal("sync: WaitGroup.Add called from multiple synctest bubbles") case synctest.CurrentBubble: bubbled = true - state := wg.state.Or(waitGroupBubbleFlag) - if state != 0 && state&waitGroupBubbleFlag == 0 { - // Add has been called from outside this bubble. - fatal("sync: WaitGroup.Add called from inside and outside synctest bubble") + // Use compare-and-swap loop to implement atomic Or operation + // since race detector doesn't have __tsan_go_atomic64_fetch_or + for { + old := wg.state.Load() + new := old | waitGroupBubbleFlag + if wg.state.CompareAndSwap(old, new) { + state := old + if state != 0 && state&waitGroupBubbleFlag == 0 { + // Add has been called from outside this bubble. + fatal("sync: WaitGroup.Add called from inside and outside synctest bubble") + } + break + } } } } -- 2.47.2