mirror of
https://github.com/golang/go
synced 2024-11-21 21:44:40 -07:00
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 https://golang.org/cl/190074
This commit is contained in:
parent
dfc0ed9559
commit
b2beb8abf0
@ -8,6 +8,7 @@ package main
|
|||||||
|
|
||||||
import "os"
|
import "os"
|
||||||
import "runtime"
|
import "runtime"
|
||||||
|
import "sync"
|
||||||
|
|
||||||
var randx int;
|
var randx int;
|
||||||
|
|
||||||
@ -28,9 +29,11 @@ type Chan struct {
|
|||||||
var
|
var
|
||||||
(
|
(
|
||||||
nproc int;
|
nproc int;
|
||||||
|
nprocLock sync.Mutex;
|
||||||
cval int;
|
cval int;
|
||||||
end int = 10000;
|
end int = 10000;
|
||||||
totr,tots int;
|
totr,tots int;
|
||||||
|
totLock sync.Mutex;
|
||||||
nc *Chan;
|
nc *Chan;
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -39,6 +42,14 @@ init() {
|
|||||||
nc = new(Chan);
|
nc = new(Chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func changeNproc(adjust int) int {
|
||||||
|
nprocLock.Lock()
|
||||||
|
nproc += adjust
|
||||||
|
ret := nproc
|
||||||
|
nprocLock.Unlock()
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func
|
func
|
||||||
mkchan(c,n int) []*Chan {
|
mkchan(c,n int) []*Chan {
|
||||||
ca := make([]*Chan, n);
|
ca := make([]*Chan, n);
|
||||||
@ -67,7 +78,9 @@ expect(v, v0 int) (newv int) {
|
|||||||
|
|
||||||
func (c *Chan) send() bool {
|
func (c *Chan) send() bool {
|
||||||
// print("send ", c.sv, "\n");
|
// print("send ", c.sv, "\n");
|
||||||
|
totLock.Lock();
|
||||||
tots++;
|
tots++;
|
||||||
|
totLock.Unlock();
|
||||||
c.sv = expect(c.sv, c.sv);
|
c.sv = expect(c.sv, c.sv);
|
||||||
if c.sv == end {
|
if c.sv == end {
|
||||||
c.sc = nil;
|
c.sc = nil;
|
||||||
@ -78,7 +91,6 @@ func (c *Chan) send() bool {
|
|||||||
|
|
||||||
func
|
func
|
||||||
send(c *Chan) {
|
send(c *Chan) {
|
||||||
nproc++; // total goroutines running
|
|
||||||
for {
|
for {
|
||||||
for r:=nrand(10); r>=0; r-- {
|
for r:=nrand(10); r>=0; r-- {
|
||||||
runtime.Gosched();
|
runtime.Gosched();
|
||||||
@ -88,12 +100,14 @@ send(c *Chan) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nproc--;
|
changeNproc(-1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Chan) recv(v int) bool {
|
func (c *Chan) recv(v int) bool {
|
||||||
// print("recv ", v, "\n");
|
// print("recv ", v, "\n");
|
||||||
|
totLock.Lock();
|
||||||
totr++;
|
totr++;
|
||||||
|
totLock.Unlock();
|
||||||
c.rv = expect(c.rv, v);
|
c.rv = expect(c.rv, v);
|
||||||
if c.rv == end {
|
if c.rv == end {
|
||||||
c.rc = nil;
|
c.rc = nil;
|
||||||
@ -106,7 +120,6 @@ func
|
|||||||
recv(c *Chan) {
|
recv(c *Chan) {
|
||||||
var v int;
|
var v int;
|
||||||
|
|
||||||
nproc++; // total goroutines running
|
|
||||||
for {
|
for {
|
||||||
for r:=nrand(10); r>=0; r-- {
|
for r:=nrand(10); r>=0; r-- {
|
||||||
runtime.Gosched();
|
runtime.Gosched();
|
||||||
@ -116,14 +129,13 @@ recv(c *Chan) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nproc--;
|
changeNproc(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
func
|
func
|
||||||
sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan) {
|
sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan) {
|
||||||
var v int;
|
var v int;
|
||||||
|
|
||||||
nproc++; // total goroutines running
|
|
||||||
a := 0; // local chans running
|
a := 0; // local chans running
|
||||||
|
|
||||||
if r0.rc != nil { a++ }
|
if r0.rc != nil { a++ }
|
||||||
@ -178,12 +190,13 @@ sel(r0,r1,r2,r3, s0,s1,s2,s3 *Chan) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
nproc--;
|
changeNproc(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// direct send to direct recv
|
// direct send to direct recv
|
||||||
func
|
func
|
||||||
test1(c *Chan) {
|
test1(c *Chan) {
|
||||||
|
changeNproc(2)
|
||||||
go send(c);
|
go send(c);
|
||||||
go recv(c);
|
go recv(c);
|
||||||
}
|
}
|
||||||
@ -193,11 +206,13 @@ func
|
|||||||
test2(c int) {
|
test2(c int) {
|
||||||
ca := mkchan(c,4);
|
ca := mkchan(c,4);
|
||||||
|
|
||||||
|
changeNproc(4)
|
||||||
go send(ca[0]);
|
go send(ca[0]);
|
||||||
go send(ca[1]);
|
go send(ca[1]);
|
||||||
go send(ca[2]);
|
go send(ca[2]);
|
||||||
go send(ca[3]);
|
go send(ca[3]);
|
||||||
|
|
||||||
|
changeNproc(1)
|
||||||
go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
|
go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,11 +221,13 @@ func
|
|||||||
test3(c int) {
|
test3(c int) {
|
||||||
ca := mkchan(c,4);
|
ca := mkchan(c,4);
|
||||||
|
|
||||||
|
changeNproc(4)
|
||||||
go recv(ca[0]);
|
go recv(ca[0]);
|
||||||
go recv(ca[1]);
|
go recv(ca[1]);
|
||||||
go recv(ca[2]);
|
go recv(ca[2]);
|
||||||
go recv(ca[3]);
|
go recv(ca[3]);
|
||||||
|
|
||||||
|
changeNproc(1)
|
||||||
go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
|
go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -219,6 +236,7 @@ func
|
|||||||
test4(c int) {
|
test4(c int) {
|
||||||
ca := mkchan(c,4);
|
ca := mkchan(c,4);
|
||||||
|
|
||||||
|
changeNproc(2)
|
||||||
go sel(nc,nc,nc,nc, ca[0],ca[1],ca[2],ca[3]);
|
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);
|
go sel(ca[0],ca[1],ca[2],ca[3], nc,nc,nc,nc);
|
||||||
}
|
}
|
||||||
@ -227,6 +245,7 @@ func
|
|||||||
test5(c int) {
|
test5(c int) {
|
||||||
ca := mkchan(c,8);
|
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[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]);
|
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) {
|
test6(c int) {
|
||||||
ca := mkchan(c,12);
|
ca := mkchan(c,12);
|
||||||
|
|
||||||
|
changeNproc(4)
|
||||||
go send(ca[4]);
|
go send(ca[4]);
|
||||||
go send(ca[5]);
|
go send(ca[5]);
|
||||||
go send(ca[6]);
|
go send(ca[6]);
|
||||||
go send(ca[7]);
|
go send(ca[7]);
|
||||||
|
|
||||||
|
changeNproc(4)
|
||||||
go recv(ca[8]);
|
go recv(ca[8]);
|
||||||
go recv(ca[9]);
|
go recv(ca[9]);
|
||||||
go recv(ca[10]);
|
go recv(ca[10]);
|
||||||
go recv(ca[11]);
|
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[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]);
|
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
|
func
|
||||||
wait() {
|
wait() {
|
||||||
runtime.Gosched();
|
runtime.Gosched();
|
||||||
for nproc != 0 {
|
for changeNproc(0) != 0 {
|
||||||
runtime.Gosched();
|
runtime.Gosched();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user