On Tuesday, 22 January 2013 at 10:27:58 UTC, bearophile wrote:
The Go language has four different solutions, one of them is:
http://rosettacode.org/wiki/Atomic_updates#Lock-free


From the site:

This version uses no locking for the phase where the
two clients are updating the buckets. Instead it
watches for collisions and retries as needed.

func (bl *lfList) transfer(b1, b2, a int, ux int) {
    if b1 == b2 {
        return
    }
    bl.RLock()
    for {
        t := int32(a)
        v1 := atomic.LoadInt32(&bl.b[b1])
        if t > v1 {
            t = v1
        }
        if atomic.CompareAndSwapInt32(&bl.b[b1], v1, v1-t) {
            atomic.AddInt32(&bl.b[b2], t)
            break
        }
        // else retry
    }
    bl.tc[ux]++
    bl.RUnlock()
    runtime.Gosched()
}

Is that solution actually correct?
If I am not mistaken, the buckets are in an inconsistent state between CompareAndSwapInt32 and AddInt32.

Reply via email to