以下无锁代码是否表现出竞争条件?

Does the following lock-free code exhibit a race-condition?

Kubernetes Go repo on Github.com,

有一个 HighWaterMark 数据结构的无锁实现。此代码依赖于原子操作来实现没有数据竞争的线程安全代码。

// HighWaterMark is a thread-safe object for tracking the maximum value seen
// for some quantity.
type HighWaterMark int64

// Update returns true if and only if 'current' is the highest value ever seen.
func (hwm *HighWaterMark) Update(current int64) bool {
    for {
        old := atomic.LoadInt64((*int64)(hwm))
        if current <= old {
            return false
        }
        if atomic.CompareAndSwapInt64((*int64)(hwm), old, current) {
            return true
        }
    }
}

此代码依赖于标准库中的 atomic.LoadInt64atomic.CompareAndSwapInt64 函数来实现无数据竞争的代码......我相信它确实如此,但我相信还有另一个竞争问题条件。

如果两个竞争线程 (goroutines) 正在执行此类代码,则存在一种边缘情况,即在第一个线程中出现 atomic.LoadInt64 之后,第二个线程可能已换出更高的值.但是在第一个线程 认为 之后 current int64 实际上大于 old int64 将发生交换。由于观察到陈旧的 old 值,此交换将有效地降低存储值。

如果中间有另一个线程,CompareAndSwap 将失败并且循环将重新开始。

将 CompareAndSwap 视为

if actual == expected { 
   actual = newval
}

但自动完成

所以这段代码表示:

old = hwm // but done in a thread safe atomic read way
if old < current {
   set hwm to current if hwm == old // atomically compare and then set value
}

当 CAS (CompareAndSwap) 失败时,它 returns 为假,导致循环重新开始,直到:

a) "current" 不大于 hwm

b) 它成功地执行了 Load,然后是 CompareAndSwap,中间没有另一个线程