]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: convert closechan/chanlen/chancap to Go
authorKeith Randall <khr@golang.org>
Fri, 29 Aug 2014 04:35:59 +0000 (21:35 -0700)
committerKeith Randall <khr@golang.org>
Fri, 29 Aug 2014 04:35:59 +0000 (21:35 -0700)
LGTM=bradfitz, rsc
R=golang-codereviews, bradfitz, rsc
CC=golang-codereviews
https://golang.org/cl/135150043

src/pkg/runtime/chan.go
src/pkg/runtime/chan.goc
src/pkg/runtime/thunk.s

index fe7e72edc2594ae4f6d75ffc7768d3f03ee5fb09..239c29f9e277525fb2c0d99f8747d158b5aaba58 100644 (file)
@@ -150,12 +150,7 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
                                memmove(unsafe.Pointer(sg.elem), ep, uintptr(c.elemsize))
                        }
                        if sg.releasetime != 0 {
-                               // Yes, this is ugly.  On 64-bit sg.releasetime has type
-                               // int.  On 32-bit it has type int64.  There's no easy way
-                               // to assign to both types in Go.  At some point we'll
-                               // write the Go types directly instead of generating them
-                               // via the C types.  At that point, this nastiness goes away.
-                               *(*int64)(unsafe.Pointer(&sg.releasetime)) = cputicks()
+                               sg.releasetime = cputicks()
                        }
                        goready(recvg)
                        return true
@@ -248,7 +243,7 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
                recvg := sg.g
                unlock(&c.lock)
                if sg.releasetime != 0 {
-                       *(*int64)(unsafe.Pointer(&sg.releasetime)) = cputicks()
+                       sg.releasetime = cputicks()
                }
                goready(recvg)
        } else {
@@ -260,6 +255,72 @@ func chansend(t *chantype, c *hchan, ep unsafe.Pointer, block bool, callerpc uin
        return true
 }
 
+func closechan(c *hchan) {
+       if c == nil {
+               panic("close of nil channel")
+       }
+
+       lock(&c.lock)
+       if c.closed != 0 {
+               unlock(&c.lock)
+               panic("close of closed channel")
+       }
+
+       if raceenabled {
+               callerpc := getcallerpc(unsafe.Pointer(&c))
+               fn := closechan
+               pc := **(**uintptr)(unsafe.Pointer(&fn))
+               racewritepc(unsafe.Pointer(c), callerpc, pc)
+               racerelease(unsafe.Pointer(c))
+       }
+
+       c.closed = 1
+
+       // release all readers
+       for {
+               sg := c.recvq.dequeue()
+               if sg == nil {
+                       break
+               }
+               gp := sg.g
+               gp.param = nil
+               if sg.releasetime != 0 {
+                       sg.releasetime = cputicks()
+               }
+               goready(gp)
+       }
+
+       // release all writers
+       for {
+               sg := c.sendq.dequeue()
+               if sg == nil {
+                       break
+               }
+               gp := sg.g
+               gp.param = nil
+               if sg.releasetime != 0 {
+                       sg.releasetime = cputicks()
+               }
+               goready(gp)
+       }
+
+       unlock(&c.lock)
+}
+
+func reflect_chanlen(c *hchan) int {
+       if c == nil {
+               return 0
+       }
+       return int(c.qcount)
+}
+
+func reflect_chancap(c *hchan) int {
+       if c == nil {
+               return 0
+       }
+       return int(c.dataqsiz)
+}
+
 func (q *waitq) enqueue(sgp *sudog) {
        sgp.next = nil
        if q.first == nil {
index 7d6ee1be2b0f707082911c1a1242151c20ca2a0c..a4a0d1d9baec7efb6f4429250538a8f0f0a2faf5 100644 (file)
@@ -1005,81 +1005,6 @@ func reflect·rselect(cases Slice) (chosen int, recvOK bool) {
        chosen = (intgo)(uintptr)selectgo(&sel);
 }
 
-static void closechan(Hchan *c, void *pc);
-
-#pragma textflag NOSPLIT
-func closechan(c *Hchan) {
-       closechan(c, runtime·getcallerpc(&c));
-}
-
-#pragma textflag NOSPLIT
-func reflect·chanclose(c *Hchan) {
-       closechan(c, runtime·getcallerpc(&c));
-}
-
-static void
-closechan(Hchan *c, void *pc)
-{
-       SudoG *sg;
-       G* gp;
-
-       if(c == nil)
-               runtime·panicstring("close of nil channel");
-
-       runtime·lock(&c->lock);
-       if(c->closed) {
-               runtime·unlock(&c->lock);
-               runtime·panicstring("close of closed channel");
-       }
-
-       if(raceenabled) {
-               runtime·racewritepc(c, pc, runtime·closechan);
-               runtime·racerelease(c);
-       }
-
-       c->closed = true;
-
-       // release all readers
-       for(;;) {
-               sg = dequeue(&c->recvq);
-               if(sg == nil)
-                       break;
-               gp = sg->g;
-               gp->param = nil;
-               if(sg->releasetime)
-                       sg->releasetime = runtime·cputicks();
-               runtime·ready(gp);
-       }
-
-       // release all writers
-       for(;;) {
-               sg = dequeue(&c->sendq);
-               if(sg == nil)
-                       break;
-               gp = sg->g;
-               gp->param = nil;
-               if(sg->releasetime)
-                       sg->releasetime = runtime·cputicks();
-               runtime·ready(gp);
-       }
-
-       runtime·unlock(&c->lock);
-}
-
-func reflect·chanlen(c *Hchan) (len int) {
-       if(c == nil)
-               len = 0;
-       else
-               len = c->qcount;
-}
-
-func reflect·chancap(c *Hchan) (cap int) {
-       if(c == nil)
-               cap = 0;
-       else
-               cap = c->dataqsiz;
-}
-
 static SudoG*
 dequeue(WaitQ *q)
 {
index 4d2a49829c4b83b87caaa06278f2c9344ce1f50f..6093656c6f9779e32b8fab5e43f119e193b61855 100644 (file)
@@ -52,3 +52,12 @@ TEXT bytes·Compare(SB),NOSPLIT,$0-0
 
 TEXT runtime·reflectcall(SB), NOSPLIT, $0-0
        JMP     reflect·call(SB)
+
+TEXT reflect·chanclose(SB), NOSPLIT, $0-0
+       JMP     runtime·closechan(SB)
+
+TEXT reflect·chanlen(SB), NOSPLIT, $0-0
+       JMP     runtime·reflect_chanlen(SB)
+
+TEXT reflect·chancap(SB), NOSPLIT, $0-0
+       JMP     runtime·reflect_chancap(SB)