Atomic updates

monarch_dodra monarchdodra at gmail.com
Tue Jan 22 06:13:41 PST 2013


On Tuesday, 22 January 2013 at 14:10:14 UTC, qznc wrote:
> 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.

So?

buckets[from] -= realAmount; //Inconsistent state here
buckets[to  ] += realAmount;

The bottom line is that there *has* to be a point in time where 
the state is inconsistent. Your job is to make sure this 
inconsistency does not overlap and corrupt the overall state.


More information about the Digitalmars-d-learn mailing list