Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
go
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
go
Commits
e963cba8
Commit
e963cba8
authored
Jul 25, 2008
by
Ken Thompson
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
select
R=r APPROVED=r DELTA=147 (94 added, 14 deleted, 39 changed) OCL=13477 CL=13477
parent
756c63cd
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
123 additions
and
43 deletions
+123
-43
src/cmd/gc/walk.c
src/cmd/gc/walk.c
+1
-1
src/runtime/chan.c
src/runtime/chan.c
+119
-40
src/runtime/runtime.h
src/runtime/runtime.h
+3
-2
No files found.
src/cmd/gc/walk.c
View file @
e963cba8
...
...
@@ -1069,7 +1069,7 @@ walkselect(Node *sel)
walktype
(
sel
->
ninit
,
Etop
);
walktype
(
sel
->
nbody
,
Etop
);
dump
(
"sel"
,
sel
);
//
dump("sel", sel);
lineno
=
lno
;
}
...
...
src/runtime/chan.c
View file @
e963cba8
...
...
@@ -17,7 +17,8 @@ struct SudoG
{
G
*
g
;
// g and selgen constitute
byte
elem
[
8
];
// synch data element
int64
selgen
;
// a weak pointer to g
int16
offset
;
// offset of case number
int32
selgen
;
// a weak pointer to g
SudoG
*
link
;
};
...
...
@@ -162,6 +163,7 @@ sys·chansend1(Hchan* c, ...)
c
->
elemalg
->
copy
(
c
->
elemsize
,
sgr
->
elem
,
ae
);
gr
=
sgr
->
g
;
gr
->
param
=
sgr
;
gr
->
status
=
Grunnable
;
return
;
}
...
...
@@ -217,6 +219,7 @@ sys·chansend2(Hchan* c, ...)
gr
=
sgr
->
g
;
c
->
elemalg
->
copy
(
c
->
elemsize
,
sgr
->
elem
,
ae
);
gr
->
param
=
sgr
;
gr
->
status
=
Grunnable
;
*
ap
=
true
;
return
;
...
...
@@ -263,6 +266,7 @@ sys·chanrecv1(Hchan* c, ...)
c
->
elemalg
->
copy
(
c
->
elemsize
,
ae
,
sgs
->
elem
);
gs
=
sgs
->
g
;
gs
->
param
=
sgs
;
gs
->
status
=
Grunnable
;
freesg
(
c
,
sgs
);
...
...
@@ -319,6 +323,7 @@ sys·chanrecv2(Hchan* c, ...)
c
->
elemalg
->
copy
(
c
->
elemsize
,
ae
,
sgs
->
elem
);
gs
=
sgs
->
g
;
gs
->
param
=
sgs
;
gs
->
status
=
Grunnable
;
freesg
(
c
,
sgs
);
...
...
@@ -374,7 +379,7 @@ sys·selectsend(Select *sel, Hchan *c, ...)
Scase
*
cas
;
byte
*
as
,
*
ae
;
//
return val, selected, is preset to fals
e
//
nil cases do not compet
e
if
(
c
==
nil
)
return
;
...
...
@@ -421,7 +426,7 @@ sys·selectrecv(Select *sel, Hchan *c, ...)
Scase
*
cas
;
byte
*
as
;
//
return val, selected, is preset to fals
e
//
nil cases do not compet
e
if
(
c
==
nil
)
return
;
...
...
@@ -465,16 +470,21 @@ sys·selectgo(Select *sel)
uint32
p
,
o
,
i
;
Scase
*
cas
;
Hchan
*
c
;
SudoG
*
sg
;
G
*
gp
;
byte
*
ae
,
*
as
;
SudoG
*
sgr
;
G
*
gr
;
SudoG
*
sgs
;
G
*
gs
;
if
(
0
)
{
prints
(
"selectgo: sel="
);
sys
·
printpointer
(
sel
);
prints
(
"
\n
"
);
}
if
(
sel
->
ncase
<
1
)
{
throw
(
"selectgo: no cases"
);
if
(
sel
->
ncase
<
2
)
{
if
(
sel
->
ncase
<
1
)
throw
(
"selectgo: no cases"
);
// make special case of one.
}
// select a (relative) prime
...
...
@@ -486,45 +496,60 @@ sys·selectgo(Select *sel)
throw
(
"selectgo: failed to select prime"
);
}
}
// select an initial offset
o
=
fastrand2
();
p
%=
sel
->
ncase
;
o
%=
sel
->
ncase
;
// pass 1 - look for something
that can go
// pass 1 - look for something
already waiting
for
(
i
=
0
;
i
<
sel
->
ncase
;
i
++
)
{
cas
=
&
sel
->
scase
[
o
];
c
=
cas
->
chan
;
if
(
cas
->
send
)
{
if
(
c
->
dataqsiz
>
0
)
{
throw
(
"selectgo: send asynch"
);
}
sgr
=
dequeue
(
&
c
->
recvq
,
c
);
if
(
sgr
==
nil
)
continue
;
c
->
elemalg
->
copy
(
c
->
elemsize
,
sgr
->
elem
,
cas
->
u
.
elem
);
gr
=
sgr
->
g
;
gr
->
status
=
Grunnable
;
goto
retc
;
}
else
{
if
(
c
->
dataqsiz
>
0
)
{
if
(
c
->
dataqsiz
>
0
)
{
if
(
cas
->
send
)
throw
(
"selectgo: send asynch"
);
else
throw
(
"selectgo: recv asynch"
);
}
sgs
=
dequeue
(
&
c
->
sendq
,
c
);
if
(
sgs
==
nil
)
continue
;
}
if
(
cas
->
u
.
elemp
!=
nil
)
c
->
elemalg
->
copy
(
c
->
elemsize
,
cas
->
u
.
elemp
,
sgs
->
elem
);
if
(
cas
->
send
)
{
sg
=
dequeue
(
&
c
->
recvq
,
c
);
if
(
sg
!=
nil
)
goto
gotr
;
}
else
{
sg
=
dequeue
(
&
c
->
sendq
,
c
);
if
(
sg
!=
nil
)
goto
gots
;
}
gs
=
sgs
->
g
;
gs
->
status
=
Grunnable
;
o
+=
p
;
if
(
o
>=
sel
->
ncase
)
o
-=
sel
->
ncase
;
}
freesg
(
c
,
sgs
);
// pass 2 - enqueue on all chans
for
(
i
=
0
;
i
<
sel
->
ncase
;
i
++
)
{
cas
=
&
sel
->
scase
[
o
];
c
=
cas
->
chan
;
if
(
cas
->
send
)
{
sg
=
dequeue
(
&
c
->
recvq
,
c
);
if
(
sg
!=
nil
)
goto
gotr
;
// probably an error
sg
=
allocsg
(
c
);
sg
->
offset
=
o
;
c
->
elemalg
->
copy
(
c
->
elemsize
,
sg
->
elem
,
cas
->
u
.
elem
);
enqueue
(
&
c
->
sendq
,
sg
);
}
else
{
sg
=
dequeue
(
&
c
->
sendq
,
c
);
if
(
sg
!=
nil
)
goto
gots
;
// probably an error
goto
retc
;
sg
=
allocsg
(
c
);
sg
->
offset
=
o
;
enqueue
(
&
c
->
recvq
,
sg
);
}
o
+=
p
;
...
...
@@ -532,15 +557,69 @@ sys·selectgo(Select *sel)
o
-=
sel
->
ncase
;
}
if
(
debug
)
{
prints
(
"selectgo s="
);
if
(
0
)
{
prints
(
"wait: sel="
);
sys
·
printpointer
(
sel
);
prints
(
"
\n
"
);
}
g
->
status
=
Gwaiting
;
sys
·
gosched
();
if
(
0
)
{
prints
(
"wait-return: sel="
);
sys
·
printpointer
(
sel
);
prints
(
" p="
);
sys
·
printpointer
((
void
*
)
p
);
prints
(
"
\n
"
);
}
throw
(
"selectgo"
);
sg
=
g
->
param
;
o
=
sg
->
offset
;
cas
=
&
sel
->
scase
[
o
];
c
=
cas
->
chan
;
if
(
0
)
{
prints
(
"wake: sel="
);
sys
·
printpointer
(
sel
);
prints
(
" c="
);
sys
·
printpointer
(
c
);
prints
(
" o="
);
sys
·
printint
(
o
);
prints
(
"
\n
"
);
}
if
(
cas
->
send
)
goto
gots
;
gotr:
if
(
0
)
{
prints
(
"gotr: sel="
);
sys
·
printpointer
(
sel
);
prints
(
" c="
);
sys
·
printpointer
(
c
);
prints
(
" o="
);
sys
·
printint
(
o
);
prints
(
"
\n
"
);
}
c
->
elemalg
->
copy
(
c
->
elemsize
,
sg
->
elem
,
cas
->
u
.
elem
);
gp
=
sg
->
g
;
gp
->
param
=
sg
;
gp
->
status
=
Grunnable
;
goto
retc
;
gots:
if
(
0
)
{
prints
(
"gots: sel="
);
sys
·
printpointer
(
sel
);
prints
(
" c="
);
sys
·
printpointer
(
c
);
prints
(
" o="
);
sys
·
printint
(
o
);
prints
(
"
\n
"
);
}
if
(
cas
->
u
.
elemp
!=
nil
)
c
->
elemalg
->
copy
(
c
->
elemsize
,
cas
->
u
.
elemp
,
sg
->
elem
);
gp
=
sg
->
g
;
gp
->
param
=
sg
;
gp
->
status
=
Grunnable
;
freesg
(
c
,
sg
);
retc:
sys
·
setcallerpc
(
&
sel
,
cas
->
pc
);
...
...
@@ -561,7 +640,7 @@ loop:
// if sgp is stale, ignore it
if
(
sgp
->
selgen
!=
sgp
->
g
->
selgen
)
{
prints
(
"INVALID PSEUDOG POINTER
\n
"
);
//
prints("INVALID PSEUDOG POINTER\n");
freesg
(
c
,
sgp
);
goto
loop
;
}
...
...
src/runtime/runtime.h
View file @
e963cba8
...
...
@@ -107,9 +107,10 @@ struct G
byte
*
stack0
;
// first stack segment
Gobuf
sched
;
G
*
alllink
;
// on allq
int32
status
;
void
*
param
;
// passed parameter on wakeup
int16
status
;
int32
goid
;
int
64
selgen
;
// valid sudog pointer
int
32
selgen
;
// valid sudog pointer
};
struct
M
{
...
...
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