1
0
mirror of https://github.com/golang/go synced 2024-11-22 07:44:43 -07:00

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
This commit is contained in:
Dmitriy Vyukov 2011-07-21 11:30:14 -04:00 committed by Russ Cox
parent d6ed1b70ad
commit d2ab2b9f42

View File

@ -11,7 +11,7 @@ import (
// Once is an object that will perform exactly one action. // Once is an object that will perform exactly one action.
type Once struct { type Once struct {
m Mutex m Mutex
done int32 done uint32
} }
// Do calls the function f if and only if the method is being called for the // 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. // Do to be called, it will deadlock.
// //
func (o *Once) Do(f func()) { func (o *Once) Do(f func()) {
if atomic.AddInt32(&o.done, 0) == 1 { if atomic.LoadUint32(&o.done) == 1 {
return return
} }
// Slow-path. // Slow-path.
@ -38,6 +38,6 @@ func (o *Once) Do(f func()) {
defer o.m.Unlock() defer o.m.Unlock()
if o.done == 0 { if o.done == 0 {
f() f()
atomic.CompareAndSwapInt32(&o.done, 0, 1) atomic.CompareAndSwapUint32(&o.done, 0, 1)
} }
} }