diff options
Diffstat (limited to 'src/pkg/sync/rwmutex_test.go')
-rw-r--r-- | src/pkg/sync/rwmutex_test.go | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/pkg/sync/rwmutex_test.go b/src/pkg/sync/rwmutex_test.go new file mode 100644 index 000000000..ad3560800 --- /dev/null +++ b/src/pkg/sync/rwmutex_test.go @@ -0,0 +1,114 @@ +// 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. + +// GOMAXPROCS=10 gotest + +package sync_test + +import ( + "fmt"; + "runtime"; + . "sync"; + "testing"; +) + +func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) { + m.RLock(); + clocked <- true; + <-cunlock; + m.RUnlock(); + cdone <- true; +} + +func doTestParallelReaders(numReaders, gomaxprocs int) { + runtime.GOMAXPROCS(gomaxprocs); + var m RWMutex; + clocked := make(chan bool); + cunlock := make(chan bool); + cdone := make(chan bool); + for i := 0; i < numReaders; i++ { + go parallelReader(&m, clocked, cunlock, cdone) + } + // Wait for all parallel RLock()s to succeed. + for i := 0; i < numReaders; i++ { + <-clocked + } + for i := 0; i < numReaders; i++ { + cunlock <- true + } + // Wait for the goroutines to finish. + for i := 0; i < numReaders; i++ { + <-cdone + } +} + +func TestParallelReaders(t *testing.T) { + doTestParallelReaders(1, 4); + doTestParallelReaders(3, 4); + doTestParallelReaders(4, 2); +} + +func reader(rwm *RWMutex, num_iterations int, activity *uint32, cdone chan bool) { + for i := 0; i < num_iterations; i++ { + rwm.RLock(); + n := Xadd(activity, 1); + if n < 1 || n >= 10000 { + panic(fmt.Sprintf("wlock(%d)\n", n)) + } + for i := 0; i < 100; i++ { + } + Xadd(activity, -1); + rwm.RUnlock(); + } + cdone <- true; +} + +func writer(rwm *RWMutex, num_iterations int, activity *uint32, cdone chan bool) { + for i := 0; i < num_iterations; i++ { + rwm.Lock(); + n := Xadd(activity, 10000); + if n != 10000 { + panic(fmt.Sprintf("wlock(%d)\n", n)) + } + for i := 0; i < 100; i++ { + } + Xadd(activity, -10000); + rwm.Unlock(); + } + cdone <- true; +} + +func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) { + runtime.GOMAXPROCS(gomaxprocs); + // Number of active readers + 10000 * number of active writers. + var activity uint32; + var rwm RWMutex; + cdone := make(chan bool); + go writer(&rwm, num_iterations, &activity, cdone); + var i int; + for i = 0; i < numReaders/2; i++ { + go reader(&rwm, num_iterations, &activity, cdone) + } + go writer(&rwm, num_iterations, &activity, cdone); + for ; i < numReaders; i++ { + go reader(&rwm, num_iterations, &activity, cdone) + } + // Wait for the 2 writers and all readers to finish. + for i := 0; i < 2+numReaders; i++ { + <-cdone + } +} + +func TestRWMutex(t *testing.T) { + HammerRWMutex(1, 1, 1000); + HammerRWMutex(1, 3, 1000); + HammerRWMutex(1, 10, 1000); + HammerRWMutex(4, 1, 1000); + HammerRWMutex(4, 3, 1000); + HammerRWMutex(4, 10, 1000); + HammerRWMutex(10, 1, 1000); + HammerRWMutex(10, 3, 1000); + HammerRWMutex(10, 10, 1000); + HammerRWMutex(10, 5, 10000); +} |