]> Cypherpunks repositories - gostls13.git/commitdiff
select default
authorKen Thompson <ken@golang.org>
Thu, 6 Nov 2008 05:50:28 +0000 (21:50 -0800)
committerKen Thompson <ken@golang.org>
Thu, 6 Nov 2008 05:50:28 +0000 (21:50 -0800)
R=r
OCL=18646
CL=18646

src/cmd/gc/subr.c
src/cmd/gc/sys.go
src/cmd/gc/sysimport.c
src/cmd/gc/walk.c
src/runtime/chan.c
src/runtime/runtime.c
src/runtime/runtime.h

index fbeef81f07b90fb3dd30e8086a0b955b0013f17f..d5ef43c28e5ee39ed06ce63fc9af5ad1a03d1f72 100644 (file)
@@ -1445,6 +1445,9 @@ isselect(Node *n)
        if(s == n->sym)
                return 1;
        s = pkglookup("selectrecv", "sys");
+       if(s == n->sym)
+               return 1;
+       s = pkglookup("selectdefault", "sys");
        if(s == n->sym)
                return 1;
        return 0;
index d68d0283d7541d5d860619c1ab6d6f06a6a5dbbb..0ee9deb51bc743ce1420e7d3a53d978bef7488e7 100644 (file)
@@ -68,6 +68,7 @@ export func   chansend2(hchan *chan any, elem any) (pres bool);
 export func    newselect(size int) (sel *byte);
 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    selectdefault(sel *byte) (selected bool);
 export func    selectgo(sel *byte);
 
 export func    newarray(nel int, cap int, width int) (ary *[]any);
index 750192ef37e73aa95e00375035ac64f2f2e2c68c..02b5a86e814ced00f836fcd85c275f22c890b99e 100644 (file)
@@ -53,6 +53,7 @@ char *sysimport =
        "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.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.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"
index cdc675a9157cc8c774e833a30eda742233f36cdf..130a5ece279c3198136e9c49037b82713a3aba7d 100644 (file)
@@ -1246,6 +1246,8 @@ selcase(Node *n, Node *var)
        Node *a, *r, *on, *c;
        Type *t;
 
+       if(n->left == N)
+               goto dflt;
        c = n->left;
        if(c->op == ORECV)
                goto recv;
@@ -1329,6 +1331,14 @@ recv2:
        r = list(a, r);
        a = var;                        // sel-var
        r = list(a, r);
+       goto out;
+
+dflt:
+       // selectdefault(sel *byte);
+       on = syslook("selectdefault", 0);
+       a = var;
+       r = a;                          // sel-var
+       goto out;
 
 out:
        a = nod(OCALL, on, r);
@@ -1367,8 +1377,8 @@ walkselect(Node *sel)
 {
        Iter iter;
        Node *n, *oc, *on, *r;
-       Node *var, *bod, *res;
-       int count;
+       Node *var, *bod, *res, *def;
+       int count, op;
        int32 lno;
 
        lno = setlineno(sel);
@@ -1385,6 +1395,7 @@ walkselect(Node *sel)
        res = N;        // entire select body
        bod = N;        // body of each case
        oc = N;         // last case
+       def = N;        // default case
 
        for(count=0; n!=N; n=listnext(&iter)) {
                setlineno(n);
@@ -1395,15 +1406,22 @@ walkselect(Node *sel)
                        break;
 
                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:
-                               yyerror("select cases must be send or recv");
+                               yyerror("select cases must be send, recv or default");
                                break;
 
                        case OAS:
                                // convert new syntax (a=recv(chan)) to (recv(a,chan))
                                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;
                                }
                                n->left->right->right = n->left->right->left;
@@ -1419,6 +1437,8 @@ walkselect(Node *sel)
                                oc = selcase(n, var);
                                res = list(res, oc);
                                break;
+
+                               
                        }
                        bod = N;
                        count++;
index 3777190e29b48f09237cfd5f3bc85122ba26950a..c30cb0700464a713c88bd28eab2042280f7879f5 100644 (file)
@@ -497,14 +497,14 @@ sys·selectrecv(Select *sel, Hchan *c, ...)
        }
 }
 
+
+// selectrecv(sel *byte) (selected bool);
 void
-sys·selectdefault(Select *sel)
+sys·selectdefault(Select *sel, ...)
 {
-       int32 i, eo;
+       int32 i;
        Scase *cas;
-       Hchan *c;
        
-       c = nil;
        i = sel->ncase;
        if(i >= sel->tcase)
                throw("selectdefault: too many cases");
@@ -512,13 +512,11 @@ sys·selectdefault(Select *sel)
        cas = &sel->scase[i];
 
        cas->pc = sys·getcallerpc(&sel);
-       cas->chan = c;
+       cas->chan = nil;
 
-       eo = rnd(sizeof(sel), sizeof(c));
-       eo = rnd(eo+sizeof(c), sizeof(byte*));
-       cas->so = rnd(eo+sizeof(byte*), 1);
+       cas->so = rnd(sizeof(sel), 1);
        cas->send = 2;
-       cas->u.elemp = *(byte**)((byte*)&sel + eo);
+       cas->u.elemp = nil;
 
        if(debug) {
                prints("newselect s=");
index 5fde296700f6816599796aadda037d6132dca0cf..db31b77df3839a85134cade91c99d0160bef204b 100644 (file)
@@ -4,7 +4,8 @@
 
 #include "runtime.h"
 
-int32  panicking = 0;
+int32  panicking       = 0;
+int32  maxround        = 8;
 
 int32
 gotraceback(void)
@@ -91,6 +92,8 @@ rnd(uint32 n, uint32 m)
 {
        uint32 r;
 
+       if(m > maxround)
+               m = maxround;
        r = n % m;
        if(r)
                n += m-r;
index f182aebae798757d6006855dacdc73d0dade9a24..30fa915b484717cc478939821944f5d743dd1615 100644 (file)
@@ -190,6 +190,7 @@ G*  allg;
 int32  goidgen;
 extern int32   gomaxprocs;
 extern int32   panicking;
+extern int32   maxround;
 
 /*
  * common functions and data