From: Dmitriy Vyukov Date: Thu, 21 Jul 2011 15:30:14 +0000 (-0400) Subject: sync: improve Once fast path X-Git-Tag: weekly.2011-07-29~100 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=d2ab2b9f42399c9a9b481dcb2abe4dc47b4a619b;p=gostls13.git sync: improve Once fast path Use atomic.LoadUint32(&done) instead of atomic.AddInt32(&done, 0) on fast path. benchmark old ns/op new ns/op delta BenchmarkOnce 13.40 7.26 -45.82% BenchmarkOnce-2 22.90 4.04 -82.36% BenchmarkOnce-4 25.60 2.16 -91.56% BenchmarkOnce-8 25.80 1.38 -94.65% BenchmarkOnce-16 24.40 1.33 -94.55% (on HP Z600, 2 x Intel Xeon E5620, 8 HT cores, 2.4 GHz) R=golang-dev, rsc CC=golang-dev https://golang.org/cl/4787041 --- diff --git a/src/pkg/sync/once.go b/src/pkg/sync/once.go index 447b71dcb7..04b714a3e7 100644 --- a/src/pkg/sync/once.go +++ b/src/pkg/sync/once.go @@ -11,7 +11,7 @@ import ( // Once is an object that will perform exactly one action. type Once struct { m Mutex - done int32 + done uint32 } // Do calls the function f if and only if the method is being called for the @@ -30,7 +30,7 @@ type Once struct { // Do to be called, it will deadlock. // func (o *Once) Do(f func()) { - if atomic.AddInt32(&o.done, 0) == 1 { + if atomic.LoadUint32(&o.done) == 1 { return } // Slow-path. @@ -38,6 +38,6 @@ func (o *Once) Do(f func()) { defer o.m.Unlock() if o.done == 0 { f() - atomic.CompareAndSwapInt32(&o.done, 0, 1) + atomic.CompareAndSwapUint32(&o.done, 0, 1) } }