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.
4
5package sync_test
6
7import (
8	"runtime"
9	. "sync"
10	"testing"
11)
12
13func BenchmarkSemaUncontended(b *testing.B) {
14	type PaddedSem struct {
15		sem uint32
16		pad [32]uint32
17	}
18	b.RunParallel(func(pb *testing.PB) {
19		sem := new(PaddedSem)
20		for pb.Next() {
21			Runtime_Semrelease(&sem.sem, false, 0)
22			Runtime_Semacquire(&sem.sem)
23		}
24	})
25}
26
27func benchmarkSema(b *testing.B, block, work bool) {
28	if b.N == 0 {
29		return
30	}
31	sem := uint32(0)
32	if block {
33		done := make(chan bool)
34		go func() {
35			for p := 0; p < runtime.GOMAXPROCS(0)/2; p++ {
36				Runtime_Semacquire(&sem)
37			}
38			done <- true
39		}()
40		defer func() {
41			<-done
42		}()
43	}
44	b.RunParallel(func(pb *testing.PB) {
45		foo := 0
46		for pb.Next() {
47			Runtime_Semrelease(&sem, false, 0)
48			if work {
49				for i := 0; i < 100; i++ {
50					foo *= 2
51					foo /= 2
52				}
53			}
54			Runtime_Semacquire(&sem)
55		}
56		_ = foo
57		Runtime_Semrelease(&sem, false, 0)
58	})
59}
60
61func BenchmarkSemaSyntNonblock(b *testing.B) {
62	benchmarkSema(b, false, false)
63}
64
65func BenchmarkSemaSyntBlock(b *testing.B) {
66	benchmarkSema(b, true, false)
67}
68
69func BenchmarkSemaWorkNonblock(b *testing.B) {
70	benchmarkSema(b, false, true)
71}
72
73func BenchmarkSemaWorkBlock(b *testing.B) {
74	benchmarkSema(b, true, true)
75}
76