mirror of
https://github.com/golang/go
synced 2024-11-26 08:38:01 -07:00
select default
R=r OCL=18646 CL=18646
This commit is contained in:
parent
a6af484328
commit
79fbbe37a7
@ -1445,6 +1445,9 @@ isselect(Node *n)
|
|||||||
if(s == n->sym)
|
if(s == n->sym)
|
||||||
return 1;
|
return 1;
|
||||||
s = pkglookup("selectrecv", "sys");
|
s = pkglookup("selectrecv", "sys");
|
||||||
|
if(s == n->sym)
|
||||||
|
return 1;
|
||||||
|
s = pkglookup("selectdefault", "sys");
|
||||||
if(s == n->sym)
|
if(s == n->sym)
|
||||||
return 1;
|
return 1;
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -68,6 +68,7 @@ export func chansend2(hchan *chan any, elem any) (pres bool);
|
|||||||
export func newselect(size int) (sel *byte);
|
export func newselect(size int) (sel *byte);
|
||||||
export func selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
|
export func selectsend(sel *byte, hchan *chan any, elem any) (selected bool);
|
||||||
export func selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
|
export func selectrecv(sel *byte, hchan *chan any, elem *any) (selected bool);
|
||||||
|
export func selectdefault(sel *byte) (selected bool);
|
||||||
export func selectgo(sel *byte);
|
export func selectgo(sel *byte);
|
||||||
|
|
||||||
export func newarray(nel int, cap int, width int) (ary *[]any);
|
export func newarray(nel int, cap int, width int) (ary *[]any);
|
||||||
|
@ -53,6 +53,7 @@ char *sysimport =
|
|||||||
"export func sys.newselect (size int) (sel *uint8)\n"
|
"export func sys.newselect (size int) (sel *uint8)\n"
|
||||||
"export func sys.selectsend (sel *uint8, hchan *chan any, elem any) (selected bool)\n"
|
"export func sys.selectsend (sel *uint8, hchan *chan any, elem any) (selected bool)\n"
|
||||||
"export func sys.selectrecv (sel *uint8, hchan *chan any, elem *any) (selected bool)\n"
|
"export func sys.selectrecv (sel *uint8, hchan *chan any, elem *any) (selected bool)\n"
|
||||||
|
"export func sys.selectdefault (sel *uint8) (selected bool)\n"
|
||||||
"export func sys.selectgo (sel *uint8)\n"
|
"export func sys.selectgo (sel *uint8)\n"
|
||||||
"export func sys.newarray (nel int, cap int, width int) (ary *[]any)\n"
|
"export func sys.newarray (nel int, cap int, width int) (ary *[]any)\n"
|
||||||
"export func sys.arraysliced (old *[]any, lb int, hb int, width int) (ary *[]any)\n"
|
"export func sys.arraysliced (old *[]any, lb int, hb int, width int) (ary *[]any)\n"
|
||||||
|
@ -1246,6 +1246,8 @@ selcase(Node *n, Node *var)
|
|||||||
Node *a, *r, *on, *c;
|
Node *a, *r, *on, *c;
|
||||||
Type *t;
|
Type *t;
|
||||||
|
|
||||||
|
if(n->left == N)
|
||||||
|
goto dflt;
|
||||||
c = n->left;
|
c = n->left;
|
||||||
if(c->op == ORECV)
|
if(c->op == ORECV)
|
||||||
goto recv;
|
goto recv;
|
||||||
@ -1329,6 +1331,14 @@ recv2:
|
|||||||
r = list(a, r);
|
r = list(a, r);
|
||||||
a = var; // sel-var
|
a = var; // sel-var
|
||||||
r = list(a, r);
|
r = list(a, r);
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dflt:
|
||||||
|
// selectdefault(sel *byte);
|
||||||
|
on = syslook("selectdefault", 0);
|
||||||
|
a = var;
|
||||||
|
r = a; // sel-var
|
||||||
|
goto out;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
a = nod(OCALL, on, r);
|
a = nod(OCALL, on, r);
|
||||||
@ -1367,8 +1377,8 @@ walkselect(Node *sel)
|
|||||||
{
|
{
|
||||||
Iter iter;
|
Iter iter;
|
||||||
Node *n, *oc, *on, *r;
|
Node *n, *oc, *on, *r;
|
||||||
Node *var, *bod, *res;
|
Node *var, *bod, *res, *def;
|
||||||
int count;
|
int count, op;
|
||||||
int32 lno;
|
int32 lno;
|
||||||
|
|
||||||
lno = setlineno(sel);
|
lno = setlineno(sel);
|
||||||
@ -1385,6 +1395,7 @@ walkselect(Node *sel)
|
|||||||
res = N; // entire select body
|
res = N; // entire select body
|
||||||
bod = N; // body of each case
|
bod = N; // body of each case
|
||||||
oc = N; // last case
|
oc = N; // last case
|
||||||
|
def = N; // default case
|
||||||
|
|
||||||
for(count=0; n!=N; n=listnext(&iter)) {
|
for(count=0; n!=N; n=listnext(&iter)) {
|
||||||
setlineno(n);
|
setlineno(n);
|
||||||
@ -1395,15 +1406,22 @@ walkselect(Node *sel)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case OXCASE:
|
case OXCASE:
|
||||||
switch(n->left->op) {
|
if(n->left == N) {
|
||||||
|
op = ORECV; // actual value not used
|
||||||
|
if(def != N)
|
||||||
|
yyerror("only one default select allowed");
|
||||||
|
def = n;
|
||||||
|
} else
|
||||||
|
op = n->left->op;
|
||||||
|
switch(op) {
|
||||||
default:
|
default:
|
||||||
yyerror("select cases must be send or recv");
|
yyerror("select cases must be send, recv or default");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OAS:
|
case OAS:
|
||||||
// convert new syntax (a=recv(chan)) to (recv(a,chan))
|
// convert new syntax (a=recv(chan)) to (recv(a,chan))
|
||||||
if(n->left->right == N || n->left->right->op != ORECV) {
|
if(n->left->right == N || n->left->right->op != ORECV) {
|
||||||
yyerror("select cases must be send or recv");
|
yyerror("select cases must be send, recv or default");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
n->left->right->right = n->left->right->left;
|
n->left->right->right = n->left->right->left;
|
||||||
@ -1419,6 +1437,8 @@ walkselect(Node *sel)
|
|||||||
oc = selcase(n, var);
|
oc = selcase(n, var);
|
||||||
res = list(res, oc);
|
res = list(res, oc);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
bod = N;
|
bod = N;
|
||||||
count++;
|
count++;
|
||||||
|
@ -497,14 +497,14 @@ sys·selectrecv(Select *sel, Hchan *c, ...)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// selectrecv(sel *byte) (selected bool);
|
||||||
void
|
void
|
||||||
sys·selectdefault(Select *sel)
|
sys·selectdefault(Select *sel, ...)
|
||||||
{
|
{
|
||||||
int32 i, eo;
|
int32 i;
|
||||||
Scase *cas;
|
Scase *cas;
|
||||||
Hchan *c;
|
|
||||||
|
|
||||||
c = nil;
|
|
||||||
i = sel->ncase;
|
i = sel->ncase;
|
||||||
if(i >= sel->tcase)
|
if(i >= sel->tcase)
|
||||||
throw("selectdefault: too many cases");
|
throw("selectdefault: too many cases");
|
||||||
@ -512,13 +512,11 @@ sys·selectdefault(Select *sel)
|
|||||||
cas = &sel->scase[i];
|
cas = &sel->scase[i];
|
||||||
|
|
||||||
cas->pc = sys·getcallerpc(&sel);
|
cas->pc = sys·getcallerpc(&sel);
|
||||||
cas->chan = c;
|
cas->chan = nil;
|
||||||
|
|
||||||
eo = rnd(sizeof(sel), sizeof(c));
|
cas->so = rnd(sizeof(sel), 1);
|
||||||
eo = rnd(eo+sizeof(c), sizeof(byte*));
|
|
||||||
cas->so = rnd(eo+sizeof(byte*), 1);
|
|
||||||
cas->send = 2;
|
cas->send = 2;
|
||||||
cas->u.elemp = *(byte**)((byte*)&sel + eo);
|
cas->u.elemp = nil;
|
||||||
|
|
||||||
if(debug) {
|
if(debug) {
|
||||||
prints("newselect s=");
|
prints("newselect s=");
|
||||||
|
@ -4,7 +4,8 @@
|
|||||||
|
|
||||||
#include "runtime.h"
|
#include "runtime.h"
|
||||||
|
|
||||||
int32 panicking = 0;
|
int32 panicking = 0;
|
||||||
|
int32 maxround = 8;
|
||||||
|
|
||||||
int32
|
int32
|
||||||
gotraceback(void)
|
gotraceback(void)
|
||||||
@ -91,6 +92,8 @@ rnd(uint32 n, uint32 m)
|
|||||||
{
|
{
|
||||||
uint32 r;
|
uint32 r;
|
||||||
|
|
||||||
|
if(m > maxround)
|
||||||
|
m = maxround;
|
||||||
r = n % m;
|
r = n % m;
|
||||||
if(r)
|
if(r)
|
||||||
n += m-r;
|
n += m-r;
|
||||||
|
@ -190,6 +190,7 @@ G* allg;
|
|||||||
int32 goidgen;
|
int32 goidgen;
|
||||||
extern int32 gomaxprocs;
|
extern int32 gomaxprocs;
|
||||||
extern int32 panicking;
|
extern int32 panicking;
|
||||||
|
extern int32 maxround;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* common functions and data
|
* common functions and data
|
||||||
|
Loading…
Reference in New Issue
Block a user