diff options
Diffstat (limited to 'src/pkg/sync/once_test.go')
-rw-r--r-- | src/pkg/sync/once_test.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/src/pkg/sync/once_test.go b/src/pkg/sync/once_test.go new file mode 100644 index 000000000..157a3667a --- /dev/null +++ b/src/pkg/sync/once_test.go @@ -0,0 +1,62 @@ +// Copyright 2009 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package sync_test + +import ( + . "sync" + "sync/atomic" + "runtime" + "testing" +) + +type one int + +func (o *one) Increment() { + *o++ +} + +func run(once *Once, o *one, c chan bool) { + once.Do(func() { o.Increment() }) + c <- true +} + +func TestOnce(t *testing.T) { + o := new(one) + once := new(Once) + c := make(chan bool) + const N = 10 + for i := 0; i < N; i++ { + go run(once, o, c) + } + for i := 0; i < N; i++ { + <-c + } + if *o != 1 { + t.Errorf("once failed: %d is not 1", *o) + } +} + +func BenchmarkOnce(b *testing.B) { + const CallsPerSched = 1000 + procs := runtime.GOMAXPROCS(-1) + N := int32(b.N / CallsPerSched) + var once Once + f := func() {} + c := make(chan bool, procs) + for p := 0; p < procs; p++ { + go func() { + for atomic.AddInt32(&N, -1) >= 0 { + runtime.Gosched() + for g := 0; g < CallsPerSched; g++ { + once.Do(f) + } + } + c <- true + }() + } + for p := 0; p < procs; p++ { + <-c + } +} |