]> Cypherpunks repositories - gostls13.git/commitdiff
sync: improve Once fast path
authorDmitriy Vyukov <dvyukov@google.com>
Thu, 21 Jul 2011 15:30:14 +0000 (11:30 -0400)
committerRuss Cox <rsc@golang.org>
Thu, 21 Jul 2011 15:30:14 +0000 (11:30 -0400)
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

src/pkg/sync/once.go

index 447b71dcb7af289ffb80f836fd9e2cd71f546464..04b714a3e74b883a72e7d2fcc0ef3736f08fbe5e 100644 (file)
@@ -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)
        }
 }