sync.Once.Do

63 views
Skip to first unread message

em...@franckjeannin.com

unread,
May 7, 2012, 1:24:39 PM5/7/12
to golang-dev
Why is the compare and swap necessary?
I believe atomic.StoreUint32(&o.done,1) would be just fine.
I even believe that a simple o.done = 1 would work as well since it is
protected by a lock (Memory Barrier).
Or am I missing something?

func (o *Once) Do(f func()) {
if atomic.LoadUint32(&o.done) == 1 {
return
}
// Slow-path.
o.m.Lock()
defer o.m.Unlock()
if o.done == 0 {
f()
atomic.CompareAndSwapUint32(&o.done, 0, 1)
}
}

Brad Fitzpatrick

unread,
May 7, 2012, 7:35:04 PM5/7/12
to em...@franckjeannin.com, golang-dev
I think it might've just been history, with CompareAndSwapUint32 being available in the atomic package first.

David Symonds

unread,
May 7, 2012, 7:42:02 PM5/7/12
to em...@franckjeannin.com, golang-dev
The fast-path atomic.LoadUint32 requires that operations on o.done to
be made atomically, which is why doing "o.done = 1" under the lock is
not sufficient. StoreUint32 would work fine too; it's probably a CAS
for historic reasons, as Brad suggested.


Dave.

Dmitry Vyukov

unread,
May 8, 2012, 1:24:48 AM5/8/12
to golan...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages