1 // Copyright 2013 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.
16 func TestMutexLock(t
*testing
.T
) {
29 if mu
.RWUnlock(true) {
33 if !mu
.RWLock(false) {
36 if mu
.RWUnlock(false) {
41 func TestMutexClose(t
*testing
.T
) {
43 if !mu
.IncrefAndClose() {
56 if mu
.IncrefAndClose() {
61 func TestMutexCloseUnblock(t
*testing
.T
) {
62 c
:= make(chan bool, 4)
65 for i
:= 0; i
< 4; i
++ {
74 // Concurrent goroutines must not be able to read lock the mutex.
75 time
.Sleep(time
.Millisecond
)
81 mu
.IncrefAndClose() // Must unblock the readers.
82 for i
:= 0; i
< 4; i
++ {
85 case <-time
.After(10 * time
.Second
):
92 if !mu
.RWUnlock(true) {
97 func TestMutexPanic(t
*testing
.T
) {
98 ensurePanics
:= func(f
func()) {
100 if recover() == nil {
101 t
.Fatal("does not panic")
108 ensurePanics(func() { mu
.Decref() })
109 ensurePanics(func() { mu
.RWUnlock(true) })
110 ensurePanics(func() { mu
.RWUnlock(false) })
112 ensurePanics(func() { mu
.Incref(); mu
.Decref(); mu
.Decref() })
113 ensurePanics(func() { mu
.RWLock(true); mu
.RWUnlock(true); mu
.RWUnlock(true) })
114 ensurePanics(func() { mu
.RWLock(false); mu
.RWUnlock(false); mu
.RWUnlock(false) })
116 // ensure that it's still not broken
125 func TestMutexOverflowPanic(t
*testing
.T
) {
129 t
.Fatal("did not panic")
131 msg
, ok
:= r
.(string)
133 t
.Fatalf("unexpected panic type %T", r
)
135 if !strings
.Contains(msg
, "too many") || strings
.Contains(msg
, "inconsistent") {
136 t
.Fatalf("wrong panic message %q", msg
)
141 for i
:= 0; i
< 1<<21; i
++ {
146 func TestMutexStress(t
*testing
.T
) {
153 defer runtime
.GOMAXPROCS(runtime
.GOMAXPROCS(P
))
154 done
:= make(chan bool, P
)
156 var readState
[2]uint64
157 var writeState
[2]uint64
158 for p
:= 0; p
< P
; p
++ {
163 r
:= rand
.New(rand
.NewSource(rand
.Int63()))
164 for i
:= 0; i
< N
; i
++ {
176 if !mu
.RWLock(true) {
180 // Ensure that it provides mutual exclusion for readers.
181 if readState
[0] != readState
[1] {
187 if mu
.RWUnlock(true) {
192 if !mu
.RWLock(false) {
196 // Ensure that it provides mutual exclusion for writers.
197 if writeState
[0] != writeState
[1] {
203 if mu
.RWUnlock(false) {
211 for p
:= 0; p
< P
; p
++ {
216 if !mu
.IncrefAndClose() {