]> Cypherpunks repositories - gostls13.git/commitdiff
chan flags close/closed installed
authorKen Thompson <ken@golang.org>
Fri, 13 Mar 2009 00:55:11 +0000 (17:55 -0700)
committerKen Thompson <ken@golang.org>
Fri, 13 Mar 2009 00:55:11 +0000 (17:55 -0700)
runtime not finished.

R=r
OCL=26217
CL=26217

src/cmd/gc/Makefile
src/cmd/gc/builtin.c.boot
src/cmd/gc/go.h
src/cmd/gc/go.y
src/cmd/gc/lex.c
src/cmd/gc/mkbuiltin
src/cmd/gc/subr.c
src/cmd/gc/sys.go
src/cmd/gc/walk.c
src/runtime/chan.c

index e0d0f1688732dd43da581d67214d75f602acc738..a3db97e405d976472bf72bb4e52bf76a63ce08cd 100644 (file)
@@ -41,7 +41,7 @@ y.tab.c: y.tab.h
        test -f y.tab.c && touch y.tab.c
 
 builtin.c:     sys.go unsafe.go mkbuiltin1.c mkbuiltin
-       mkbuiltin >builtin.c || \
+       ./mkbuiltin >builtin.c || \
        (echo 'mkbuiltin failed; using bootstrap copy of builtin.c'; cp builtin.c.boot builtin.c)
 
 clean:
index ccc38343d7ed5dedd1f84f6e8ef6b292ffd7dd86..9245936dd285d547ebcca7c1d8927a77d73d5ffa 100644 (file)
@@ -41,6 +41,8 @@ char *sysimport =
        "func sys.chanrecv3 (hchan chan any, elem *any) (pres bool)\n"
        "func sys.chansend1 (hchan chan any, elem any)\n"
        "func sys.chansend2 (hchan chan any, elem any) (pres bool)\n"
+       "func sys.closechan (hchan chan any)\n"
+       "func sys.closedchan (hchan chan any) (? bool)\n"
        "func sys.newselect (size int) (sel *uint8)\n"
        "func sys.selectsend (sel *uint8, hchan chan any, elem any) (selected bool)\n"
        "func sys.selectrecv (sel *uint8, hchan chan any, elem *any) (selected bool)\n"
index c87cf05ef159ee06423762e39587ad152e737436..0306eabf757173e7955d9d19e133ad9ffbf4fb40 100644 (file)
@@ -309,6 +309,7 @@ enum
        OAS, OASOP, OCASE, OXCASE, OFALL, OXFALL,
        OGOTO, OPROC, OMAKE, ONEW, OEMPTY, OSELECT,
        OLEN, OCAP, OPANIC, OPANICN, OPRINT, OPRINTN, OTYPEOF,
+       OCLOSE, OCLOSED,
 
        OOROR,
        OANDAND,
index 87e8e53f784cf1ae2a492ff2e103d44567402273..a68490fd8a778f5cf00fcce663376aa5297d3ab6 100644 (file)
@@ -15,7 +15,7 @@
 %token <val>           LLITERAL
 %token <lint>          LASOP
 %token <sym>           LNAME LBASETYPE LATYPE LPACK LACONST
-%token <sym>           LPACKAGE LIMPORT LDEFER
+%token <sym>           LPACKAGE LIMPORT LDEFER LCLOSE LCLOSED
 %token <sym>           LMAP LCHAN LINTERFACE LFUNC LSTRUCT
 %token <sym>           LCOLAS LFALL LRETURN LDDD
 %token <sym>           LLEN LCAP LPANIC LPANICN LPRINT LPRINTN
@@ -888,6 +888,14 @@ pexpr:
        {
                $$ = nod(OLEN, $3, N);
        }
+|      LCLOSE '(' expr ')'
+       {
+               $$ = nod(OCLOSE, $3, N);
+       }
+|      LCLOSED '(' expr ')'
+       {
+               $$ = nod(OCLOSED, $3, N);
+       }
 |      LCAP '(' expr ')'
        {
                $$ = nod(OCAP, $3, N);
@@ -1023,6 +1031,8 @@ sym2:
 sym3:
        LLEN
 |      LCAP
+|      LCLOSE
+|      LCLOSED
 |      LPANIC
 |      LPANICN
 |      LPRINT
index 23717d3417be7dfeea5afe8c4d4fdb0d90b5dedb..b31cf6f0c37f1e9792d3397bb9e4586b18561268 100644 (file)
@@ -1112,7 +1112,6 @@ static    struct
        "any",          LBASETYPE,      TANY,
        "sys",          LPACK,          Txxx,
 
-/* keywords */
        "break",        LBREAK,         Txxx,
        "case",         LCASE,          Txxx,
        "chan",         LCHAN,          Txxx,
@@ -1151,6 +1150,9 @@ static    struct
        "type",         LTYPE,          Txxx,
        "var",          LVAR,           Txxx,
 
+       "close",        LCLOSE,         Txxx,
+       "closed",       LCLOSED,        Txxx,
+
        "notwithstanding",              LIGNORE,        Txxx,
        "thetruthofthematter",          LIGNORE,        Txxx,
        "despiteallobjections",         LIGNORE,        Txxx,
index 8148120e0dc078c1bb193e6e5e11e7b0d485c5b2..5d0d73cc4057d2752a0f34b33eb2642be7695117 100755 (executable)
@@ -21,7 +21,8 @@ case "$USER" in
 ken | r | rsc)
        if ! cmp _builtin.c builtin.c.boot
        then
-               p4 open builtin.c.boot
+               PATH=$PATH:/usr/local/bin
+               p4 open builtin.c.boot >/dev/null
                cp _builtin.c builtin.c.boot
        fi
 esac
index 723937b2d026a5b91d2cbab44db9a4702245de8a..59bf93492145771367882a265d711c3f2aa0f923 100644 (file)
@@ -688,6 +688,8 @@ opnames[] =
        [OLABEL]        = "LABEL",
        [OLE]           = "LE",
        [OLEN]          = "LEN",
+       [OCLOSE]        = "CLOSE",
+       [OCLOSED]       = "CLOSED",
        [OCAP]          = "CAP",
        [OLIST]         = "LIST",
        [OLITERAL]      = "LITERAL",
index b121456c38c8843f3306e682ec04d23b35f9ec47..a2ef1d2592334da03bc314c2b895473c61a0b630 100644 (file)
@@ -55,6 +55,8 @@ func  chanrecv2(hchan chan any) (elem any, pres bool);
 func   chanrecv3(hchan chan any, elem *any) (pres bool);
 func   chansend1(hchan chan any, elem any);
 func   chansend2(hchan chan any, elem any) (pres bool);
+func   closechan(hchan chan any);
+func   closedchan(hchan chan any) bool;
 
 func   newselect(size int) (sel *byte);
 func   selectsend(sel *byte, hchan chan any, elem any) (selected bool);
index b8821e6f70ee74649e80a60590e3cfbf4af229b1..c113858d78f294c17c279b1e7382a68d3ed59ec8 100644 (file)
@@ -126,6 +126,8 @@ loop:
 
        case OASOP:
        case OAS:
+       case OCLOSE:
+       case OCLOSED:
        case OCALLMETH:
        case OCALLINTER:
        case OCALL:
@@ -852,6 +854,20 @@ loop:
                }
                goto ret;
 
+       case OCLOSE:
+               if(top != Etop)
+                       goto nottop;
+               walktype(n->left, Erv);         // chan
+               indir(n, chanop(n, top));
+               goto ret;
+
+       case OCLOSED:
+               if(top == Elv)
+                       goto nottop;
+               walktype(n->left, Erv);         // chan
+               indir(n, chanop(n, top));
+               goto ret;
+
        case OSEND:
                if(top == Elv)
                        goto nottop;
@@ -2447,6 +2463,40 @@ chanop(Node *n, int top)
        default:
                fatal("chanop: unknown op %O", n->op);
 
+       case OCLOSE:
+               // closechan(hchan *chan any);
+               t = fixchan(n->left->type);
+               if(t == T)
+                       break;
+
+               a = n->left;                    // chan
+               r = a;
+
+               on = syslook("closechan", 1);
+               argtype(on, t->type);   // any-1
+
+               r = nod(OCALL, on, r);
+               walktype(r, top);
+               r->type = n->type;
+               break;
+
+       case OCLOSED:
+               // closedchan(hchan *chan any) bool;
+               t = fixchan(n->left->type);
+               if(t == T)
+                       break;
+
+               a = n->left;                    // chan
+               r = a;
+
+               on = syslook("closedchan", 1);
+               argtype(on, t->type);   // any-1
+
+               r = nod(OCALL, on, r);
+               walktype(r, top);
+               n->type = r->type;
+               break;
+
        case OMAKE:
                cl = listcount(n->left);
                if(cl > 1)
index 7e6f830f6c1039f80af807ff3209560f381ba1f0..a15e50dc02976505a5e62d86ecbcfab3de8edcc2 100644 (file)
@@ -7,6 +7,14 @@
 static int32   debug   = 0;
 static Lock            chanlock;
 
+enum
+{
+       Wclosed         = 0x0001,
+       Rclosed         = 0xfffe,
+       Rincr           = 0x0002,
+       Rmax            = 0x8000,
+};
+
 typedef        struct  Hchan   Hchan;
 typedef        struct  Link    Link;
 typedef        struct  WaitQ   WaitQ;
@@ -32,7 +40,9 @@ struct        WaitQ
 
 struct Hchan
 {
-       uint32  elemsize;
+       uint16  elemsize;
+       uint16  closed;                 // Wclosed closed() hash been called
+                                       // Rclosed read-count after closed()
        uint32  dataqsiz;               // size of the circular q
        uint32  qcount;                 // total data in the q
        Alg*    elemalg;                // interface for element type
@@ -535,7 +545,6 @@ sys·selectdefault(Select *sel, ...)
        }
 }
 
-
 // selectgo(sel *byte);
 void
 sys·selectgo(Select *sel)
@@ -790,6 +799,42 @@ retc:
        *as = true;
 }
 
+// closechan(sel *byte);
+void
+sys·closechan(Hchan *c)
+{
+       if(c == nil)
+               throw("closechan: channel not allocated");
+
+       // if wclosed already set
+       // work has been done - just return
+       if(c->closed & Wclosed)
+               return;
+
+       // set wclosed
+       c->closed |= Wclosed;
+}
+
+// closedchan(sel *byte) bool;
+void
+sys·closedchan(Hchan *c, bool closed)
+{
+       if(c == nil)
+               throw("closedchan: channel not allocated");
+
+       closed = 0;
+
+       // test rclosed
+       if(c->closed & Rclosed) {
+               // see if rclosed has been set a lot
+               if(c->closed & Rmax)
+                       throw("closedchan: ignored");
+               c->closed += Rincr;
+               closed = 1;
+       }
+       FLUSH(&closed);
+}
+
 static SudoG*
 dequeue(WaitQ *q, Hchan *c)
 {