summaryrefslogtreecommitdiff
path: root/test/ken
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2010-01-19 21:09:58 -0800
committerIan Lance Taylor <iant@golang.org>2010-01-19 21:09:58 -0800
commit1c09a40de9e42d6a46d36108b3ac421794aa635a (patch)
tree01832ab7c1b901376e9398b3935a8f9882fbd595 /test/ken
parent215619c011af1166759a2b39a364f39cff721354 (diff)
downloadgolang-1c09a40de9e42d6a46d36108b3ac421794aa635a.tar.gz
Add explicit locking.
Since gcco runs goroutines in independent threads, it needs locking for the global variables. This shows up when I use ordinary increments rather than locked increments for var++. R=ken2, ken3 CC=golang-dev http://codereview.appspot.com/190074
Diffstat (limited to 'test/ken')
-rw-r--r--test/ken/chan.go36
1 files changed, 29 insertions, 7 deletions
diff --git a/test/ken/chan.go b/test/ken/chan.go
index 98bcbb09f..7504b4968 100644
--- a/test/ken/chan.go
+++ b/test/ken/chan.go
@@ -8,6 +8,7 @@ package main
import "os"
import "runtime"
+import "sync"
var randx int;
@@ -28,9 +29,11 @@ type Chan struct {
var
(
nproc int;
+ nprocLock sync.Mutex;
cval int;
end int = 10000;
totr,tots int;
+ totLock sync.Mutex;
nc *Chan;
)
@@ -39,6 +42,14 @@ init() {
nc = new(Chan);
}
+func changeNproc(adjust int) int {
+ nprocLock.Lock()
+ nproc += adjust
+ ret := nproc
+ nprocLock.Unlock()
+ return ret
+}
+
func
mkchan(c,n int) []*Chan {
ca := make([]*Chan, n);
@@ -67,7 +78,9 @@ expect(v, v0 int) (newv int) {
func (c *Chan) send() bool {
// print("send ", c.sv, "\n");
+ totLock.Lock();
tots++;
+ totLock.Unlock();
c.sv = expect(c.sv, c.sv);
if c.sv == end {
c.sc = nil;
@@ -78,7 +91,6 @@ func (c *Chan) send() bool {
func
send(c *Chan) {
- nproc++; // total goroutines running
for {
for r:=nrand(10); r>=0; r-- {
runtime.Gosched();
@@ -88,12 +100,14 @@ send(c *Chan) {
break;
}
}
- nproc--;
+ changeNproc(-1)
}
func (c *Chan) recv(v int) bool {
// print("recv ", v, "\n");
+ totLock.Lock();
totr++;
+ totLock.Unlock();
c.rv = expect(c.rv, v);
if c.rv == end {
c.rc = nil;
@@ -106,7 +120,6 @@ func
recv(c *Chan) {
var v int;
- nproc++; // total goroutines running
for {
for r:=nrand(10); r>=0; r-- {
runtime.Gosched();
@@ -116,14 +129,13 @@ recv(c *Chan) {
break;
}
}
- nproc--;
+ changeNproc(-1);
}
func
sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan) {
var v int;
- nproc++; // total goroutines running
a := 0; // local chans running
if r0.rc != nil { a++ }
@@ -178,12 +190,13 @@ sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan) {
break;
}
}
- nproc--;
+ changeNproc(-1);
}
// direct send to direct recv
func
test1(c *Chan) {
+ changeNproc(2)
go send(c);
go recv(c);
}
@@ -193,11 +206,13 @@ func
test2(c int) {
ca := mkchan(c,4);
+ changeNproc(4)
go send(ca[0]);
go send(ca[1]);
go send(ca[2]);
go send(ca[3]);
+ changeNproc(1)
go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
}
@@ -206,11 +221,13 @@ func
test3(c int) {
ca := mkchan(c,4);
+ changeNproc(4)
go recv(ca[0]);
go recv(ca[1]);
go recv(ca[2]);
go recv(ca[3]);
+ changeNproc(1)
go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
}
@@ -219,6 +236,7 @@ func
test4(c int) {
ca := mkchan(c,4);
+ changeNproc(2)
go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
}
@@ -227,6 +245,7 @@ func
test5(c int) {
ca := mkchan(c,8);
+ changeNproc(2)
go sel(ca[4],ca[5],ca[6],ca[7], ca[0],ca[1],ca[2],ca[3]);
go sel(ca[0],ca[1],ca[2],ca[3], ca[4],ca[5],ca[6],ca[7]);
}
@@ -235,16 +254,19 @@ func
test6(c int) {
ca := mkchan(c,12);
+ changeNproc(4)
go send(ca[4]);
go send(ca[5]);
go send(ca[6]);
go send(ca[7]);
+ changeNproc(4)
go recv(ca[8]);
go recv(ca[9]);
go recv(ca[10]);
go recv(ca[11]);
+ changeNproc(2)
go sel(ca[4],ca[5],ca[6],ca[7], ca[0],ca[1],ca[2],ca[3]);
go sel(ca[0],ca[1],ca[2],ca[3], ca[8],ca[9],ca[10],ca[11]);
}
@@ -253,7 +275,7 @@ test6(c int) {
func
wait() {
runtime.Gosched();
- for nproc != 0 {
+ for changeNproc(0) != 0 {
runtime.Gosched();
}
}