1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // GOMAXPROCS=10 gotest
16 func HammerSemaphore(s *uint32, loops int, cdone chan bool) {
17 for i := 0; i < loops; i++ {
24 func TestSemaphore(t *testing.T) {
28 for i := 0; i < 10; i++ {
29 go HammerSemaphore(s, 1000, c)
31 for i := 0; i < 10; i++ {
36 func BenchmarkUncontendedSemaphore(b *testing.B) {
39 HammerSemaphore(s, b.N, make(chan bool, 2))
42 func BenchmarkContendedSemaphore(b *testing.B) {
47 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
50 go HammerSemaphore(s, b.N/2, c)
51 go HammerSemaphore(s, b.N/2, c)
56 func HammerMutex(m *Mutex, loops int, cdone chan bool) {
57 for i := 0; i < loops; i++ {
64 func TestMutex(t *testing.T) {
67 for i := 0; i < 10; i++ {
68 go HammerMutex(m, 1000, c)
70 for i := 0; i < 10; i++ {
75 func TestMutexPanic(t *testing.T) {
78 t.Fatalf("unlock of unlocked mutex did not panic")
88 func BenchmarkMutexUncontended(b *testing.B) {
89 type PaddedMutex struct {
93 const CallsPerSched = 1000
94 procs := runtime.GOMAXPROCS(-1)
95 N := int32(b.N / CallsPerSched)
96 c := make(chan bool, procs)
97 for p := 0; p < procs; p++ {
100 for atomic.AddInt32(&N, -1) >= 0 {
102 for g := 0; g < CallsPerSched; g++ {
110 for p := 0; p < procs; p++ {
115 func benchmarkMutex(b *testing.B, slack, work bool) {
121 procs := runtime.GOMAXPROCS(-1)
123 procs *= GoroutineSlack
125 N := int32(b.N / CallsPerSched)
126 c := make(chan bool, procs)
128 for p := 0; p < procs; p++ {
131 for atomic.AddInt32(&N, -1) >= 0 {
133 for g := 0; g < CallsPerSched; g++ {
137 for i := 0; i < LocalWork; i++ {
147 for p := 0; p < procs; p++ {
152 func BenchmarkMutex(b *testing.B) {
153 benchmarkMutex(b, false, false)
156 func BenchmarkMutexSlack(b *testing.B) {
157 benchmarkMutex(b, true, false)
160 func BenchmarkMutexWork(b *testing.B) {
161 benchmarkMutex(b, false, true)
164 func BenchmarkMutexWorkSlack(b *testing.B) {
165 benchmarkMutex(b, true, true)