Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
G
golang
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
go
golang
Commits
8a9752dc
Commit
8a9752dc
authored
Sep 21, 2008
by
Ken Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
another async select bug
R=r OCL=15599 CL=15599
parent
9ebd9d3b
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
194 additions
and
143 deletions
+194
-143
walk.c
src/cmd/gc/walk.c
+8
-4
chan.c
src/runtime/chan.c
+1
-0
chan.go
test/ken/chan.go
+185
-139
No files found.
src/cmd/gc/walk.c
View file @
8a9752dc
...
...
@@ -563,7 +563,7 @@ loop:
goto
ret
;
}
//
structure
literal
//
array
literal
if
(
t
->
etype
==
TARRAY
)
{
r
=
arraylit
(
n
);
indir
(
n
,
r
);
...
...
@@ -2149,9 +2149,13 @@ chanop(Node *n, int top)
if
(
t
==
T
)
break
;
a
=
n
->
left
;
// hint
if
(
n
->
left
==
N
)
if
(
n
->
left
!=
N
)
{
// async buf size
a
=
nod
(
OCONV
,
n
->
left
,
N
);
a
->
type
=
types
[
TUINT32
];
}
else
a
=
nodintconst
(
0
);
r
=
a
;
a
=
nodintconst
(
algtype
(
t
->
type
));
// elem algorithm
r
=
list
(
a
,
r
);
...
...
@@ -2991,10 +2995,10 @@ arraylit(Node *n)
if
(
t
->
bound
<
0
)
{
// make it a closed array
// should there be a type copy here?
r
=
listfirst
(
&
saver
,
&
n
->
left
);
for
(
idx
=
0
;
r
!=
N
;
idx
++
)
r
=
listnext
(
&
saver
);
t
=
deep
(
t
);
t
->
bound
=
idx
;
}
...
...
src/runtime/chan.c
View file @
8a9752dc
...
...
@@ -652,6 +652,7 @@ asynr:
sg
=
dequeue
(
&
c
->
sendq
,
c
);
if
(
sg
!=
nil
)
{
gp
=
sg
->
g
;
gp
->
param
=
sg
;
freesg
(
c
,
sg
);
ready
(
gp
);
}
...
...
test/ken/chan.go
View file @
8a9752dc
...
...
@@ -8,32 +8,42 @@ package main
import
rand
"rand"
type
Chan
struct
{
sc
,
rc
*
chan
int
;
// send and recv chan
sv
,
rv
int
;
// send and recv seq
}
var
(
c0
*
chan
int
;
c1
*
chan
int
;
c2
*
chan
int
;
c3
*
chan
int
;
n
int
;
End
int
=
1000
;
totr
int
;
tots
int
;
nproc
int
;
cval
int
;
End
int
=
10000
;
totr
,
tots
int
;
nc
*
Chan
;
)
func
mkchan
(
c
uint
)
init
(
)
{
n
=
0
;
c0
=
new
(
chan
int
,
c
);
c1
=
new
(
chan
int
,
c
);
c2
=
new
(
chan
int
,
c
);
c3
=
new
(
chan
int
,
c
);
nc
=
new
(
Chan
);
}
// print("c0=", c0, "\n");
// print("c1=", c1, "\n");
// print("c2=", c2, "\n");
// print("c3=", c3, "\n");
func
mkchan
(
c
,
n
int
)
*
[]
*
Chan
{
ca
:=
new
([]
*
Chan
,
n
);
for
i
:=
0
;
i
<
n
;
i
++
{
cval
=
cval
+
100
;
ch
:=
new
(
Chan
);
ch
.
sc
=
new
(
chan
int
,
c
);
ch
.
rc
=
ch
.
sc
;
ch
.
sv
=
cval
;
ch
.
rv
=
cval
;
ca
[
i
]
=
ch
;
}
return
ca
;
}
func
...
...
@@ -48,114 +58,82 @@ expect(v, v0 int) (newv int)
panic
(
"got "
,
v
,
" expected "
,
v0
+
1
,
"
\n
"
);
}
func
(
c
*
Chan
)
send
()
bool
{
// print("send ", c.sv, "\n");
tots
++
;
c
.
sv
=
expect
(
c
.
sv
,
c
.
sv
);
if
c
.
sv
==
End
{
c
.
sc
=
nil
return
true
;
}
return
false
;
}
func
send
(
c
*
chan
int
,
v0
int
)
send
(
c
*
Chan
)
{
n
++
;
n
proc
++
;
// total goroutines running
for
{
for
r
:=
rand
.
nrand
(
10
);
r
>=
0
;
r
--
{
sys
.
gosched
();
}
c
<-
v0
;
tots
++
;
v0
=
expect
(
v0
,
v0
);
if
v0
==
End
{
c
.
sc
<-
c
.
sv
;
if
c
.
send
()
{
break
;
}
}
n
--
;
n
proc
--
;
}
func
selsend
()
func
(
c
*
Chan
)
recv
(
v
int
)
bool
{
var
v
int
;
a
:=
4
;
// local chans running
n
+=
a
;
// total chans running
v0
:=
100
;
v1
:=
200
;
v2
:=
300
;
v3
:=
400
;
// local copies of the chans
// so we can nil them out
l0
:=
c0
;
l1
:=
c1
;
l2
:=
c2
;
l3
:=
c3
;
for
{
for
r
:=
rand
.
nrand
(
5
);
r
>=
0
;
r
--
{
sys
.
gosched
();
}
select
{
case
l0
<-
v0
:
v0
=
expect
(
v0
,
v0
);
if
v0
==
End
{
l0
=
nil
;
a
--
;
}
case
l1
<-
v1
:
v1
=
expect
(
v1
,
v1
);
if
v1
==
End
{
l1
=
nil
;
a
--
;
}
case
l2
<-
v2
:
v2
=
expect
(
v2
,
v2
);
if
v2
==
End
{
l2
=
nil
;
a
--
;
}
case
l3
<-
v3
:
v3
=
expect
(
v3
,
v3
);
if
v3
==
End
{
l3
=
nil
;
a
--
;
}
}
tots
++
;
if
a
==
0
{
break
;
}
// print("recv ", v, "\n");
totr
++
;
c
.
rv
=
expect
(
c
.
rv
,
v
);
if
c
.
rv
==
End
{
c
.
rc
=
nil
;
return
true
;
}
n
-=
4
;
return
false
;
}
func
recv
(
c
*
chan
int
,
v0
int
)
recv
(
c
*
Chan
)
{
var
v
int
;
n
++
;
for
i
:=
0
;
i
<
100
;
i
++
{
n
proc
++
;
// total goroutines running
for
{
for
r
:=
rand
.
nrand
(
10
);
r
>=
0
;
r
--
{
sys
.
gosched
();
}
v
=
<-
c
;
totr
++
;
v0
=
expect
(
v0
,
v
);
if
v0
==
End
{
v
=
<-
c
.
rc
;
if
c
.
recv
(
v
)
{
break
;
}
}
n
--
;
n
proc
--
;
}
func
sel
recv
(
)
sel
(
r0
,
r1
,
r2
,
r3
,
s0
,
s1
,
s2
,
s3
*
Chan
)
{
var
v
int
;
a
:=
4
;
// local chans running
n
+=
a
;
// total chans running
v0
:=
100
;
v1
:=
200
;
v2
:=
300
;
v3
:=
400
;
nproc
++
;
// total goroutines running
a
:=
0
;
// local chans running
if
r0
.
rc
!=
nil
{
a
++
}
if
r1
.
rc
!=
nil
{
a
++
}
if
r2
.
rc
!=
nil
{
a
++
}
if
r3
.
rc
!=
nil
{
a
++
}
if
s0
.
sc
!=
nil
{
a
++
}
if
s1
.
sc
!=
nil
{
a
++
}
if
s2
.
sc
!=
nil
{
a
++
}
if
s3
.
sc
!=
nil
{
a
++
}
for
{
for
r
:=
rand
.
nrand
(
5
);
r
>=
0
;
r
--
{
...
...
@@ -163,64 +141,118 @@ selrecv()
}
select
{
case
v
=
<-
c0
:
v0
=
expect
(
v0
,
v
);
if
v0
==
End
{
case
v
=
<-
r0
.
rc
:
if
r0
.
recv
(
v
)
{
a
--
;
}
case
v
=
<-
c1
:
v1
=
expect
(
v1
,
v
);
if
v1
==
End
{
case
v
=
<-
r1
.
rc
:
if
r1
.
recv
(
v
)
{
a
--
;
}
case
v
=
<-
c2
:
v2
=
expect
(
v2
,
v
);
if
v2
==
End
{
case
v
=
<-
r2
.
rc
:
if
r2
.
recv
(
v
)
{
a
--
;
}
case
v
=
<-
c3
:
v3
=
expect
(
v3
,
v
);
if
v3
==
End
{
case
v
=
<-
r3
.
rc
:
if
r3
.
recv
(
v
)
{
a
--
;
}
case
s0
.
sc
<-
s0
.
sv
:
if
s0
.
send
()
{
a
--
;
}
case
s1
.
sc
<-
s1
.
sv
:
if
s1
.
send
()
{
a
--
;
}
case
s2
.
sc
<-
s2
.
sv
:
if
s2
.
send
()
{
a
--
;
}
case
s3
.
sc
<-
s3
.
sv
:
if
s3
.
send
()
{
a
--
;
}
}
totr
++
;
if
a
==
0
{
break
;
}
}
n
-=
4
;
n
proc
--
;
}
// direct send to direct recv
func
test1
(
c
*
chan
int
,
v0
int
)
test1
(
c
*
Chan
)
{
go
send
(
c
,
v0
);
go
recv
(
c
,
v0
);
go
send
(
c
);
go
recv
(
c
);
}
// direct send to select recv
func
test2
()
test2
(
c
int
)
{
go
send
(
c0
,
100
);
go
send
(
c1
,
200
);
go
send
(
c2
,
300
);
go
send
(
c3
,
400
);
go
selrecv
();
ca
:=
mkchan
(
c
,
4
);
go
send
(
ca
[
0
]);
go
send
(
ca
[
1
]);
go
send
(
ca
[
2
]);
go
send
(
ca
[
3
]);
go
sel
(
ca
[
0
],
ca
[
1
],
ca
[
2
],
ca
[
3
],
nc
,
nc
,
nc
,
nc
);
}
// select send to direct recv
func
test3
()
test3
(
c
int
)
{
ca
:=
mkchan
(
c
,
4
);
go
recv
(
ca
[
0
]);
go
recv
(
ca
[
1
]);
go
recv
(
ca
[
2
]);
go
recv
(
ca
[
3
]);
go
sel
(
nc
,
nc
,
nc
,
nc
,
ca
[
0
],
ca
[
1
],
ca
[
2
],
ca
[
3
]);
}
// select send to select recv
func
test4
(
c
int
)
{
ca
:=
mkchan
(
c
,
4
);
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
);
}
func
test5
(
c
int
)
{
go
recv
(
c0
,
100
);
go
recv
(
c1
,
200
);
go
recv
(
c2
,
300
);
go
recv
(
c3
,
400
);
go
selsend
();
ca
:=
mkchan
(
c
,
8
);
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
]);
}
func
test6
(
c
int
)
{
ca
:=
mkchan
(
c
,
12
);
go
send
(
ca
[
4
]);
go
send
(
ca
[
5
]);
go
send
(
ca
[
6
]);
go
send
(
ca
[
7
]);
go
recv
(
ca
[
8
]);
go
recv
(
ca
[
9
]);
go
recv
(
ca
[
10
]);
go
recv
(
ca
[
11
]);
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
]);
}
// wait for outstanding tests to finish
...
...
@@ -228,28 +260,35 @@ func
wait
()
{
sys
.
gosched
();
for
n
!=
0
{
for
n
proc
!=
0
{
sys
.
gosched
();
}
}
// run all tests with specified buffer size
func
tests
(
c
u
int
)
tests
(
c
int
)
{
mkchan
(
c
);
test1
(
c0
,
100
);
test1
(
c1
,
200
);
test1
(
c2
,
300
);
test1
(
c3
,
400
);
ca
:=
mkchan
(
c
,
4
);
test1
(
ca
[
0
]);
test1
(
ca
[
1
]);
test1
(
ca
[
2
]);
test1
(
ca
[
3
]);
wait
();
test2
(
c
);
wait
();
test3
(
c
);
wait
();
mkchan
(
c
);
test2
();
test4
(
c
);
wait
();
mkchan
(
c
);
test3
();
test5
(
c
);
wait
();
test6
(
c
);
wait
();
}
...
...
@@ -257,13 +296,20 @@ tests(c uint)
func
main
()
{
tests
(
0
);
tests
(
1
);
tests
(
10
);
tests
(
100
);
if
tots
!=
totr
||
tots
!=
3648
{
print
(
"tots="
,
tots
,
" totr="
,
totr
,
"
\n
"
);
t
:=
4
// buffer sizes
*
(
4
*
4
// tests 1,2,3,4 channels
+
8
// test 5 channels
+
12
// test 6 channels
)
*
76
;
// sends/recvs on a channel
if
tots
!=
t
||
totr
!=
t
{
print
(
"tots="
,
tots
,
" totr="
,
totr
,
" sb="
,
t
,
"
\n
"
);
sys
.
exit
(
1
);
}
sys
.
exit
(
0
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment