1
0
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:
Ken Thompson 2008-11-05 21:50:28 -08:00
parent a6af484328
commit 79fbbe37a7
7 changed files with 42 additions and 15 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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"

View File

@ -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++;

View File

@ -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=");

View File

@ -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;

View File

@ -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