]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: cleanup chan code
authorDmitry Vyukov <dvyukov@google.com>
Sat, 14 Feb 2015 13:42:51 +0000 (16:42 +0300)
committerDmitry Vyukov <dvyukov@google.com>
Mon, 2 Mar 2015 08:09:49 +0000 (08:09 +0000)
Move type definitions from chan1.go to chan.go and select.go.
Remove underscores from names.
Make c.buf unsafe.Pointer instead of *uint8.

Change-Id: I75cf8385bdb9f79eb5a7f7ad319495abbacbe942
Reviewed-on: https://go-review.googlesource.com/4900
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Dmitry Vyukov <dvyukov@google.com>

src/runtime/chan.go
src/runtime/chan1.go [deleted file]
src/runtime/select.go

index 56560f94f0d343e49c4526cd9047d61066578e8a..28af9e5a6466b31128f17e588c187c8ec33ebca4 100644 (file)
@@ -14,7 +14,24 @@ const (
        debugChan = false
 )
 
-// TODO(khr): make hchan.buf an unsafe.Pointer, not a *uint8
+type hchan struct {
+       qcount   uint           // total data in the queue
+       dataqsiz uint           // size of the circular queue
+       buf      unsafe.Pointer // points to an array of dataqsiz elements
+       elemsize uint16
+       closed   uint32
+       elemtype *_type // element type
+       sendx    uint   // send index
+       recvx    uint   // receive index
+       recvq    waitq  // list of recv waiters
+       sendq    waitq  // list of send waiters
+       lock     mutex
+}
+
+type waitq struct {
+       first *sudog
+       last  *sudog
+}
 
 //go:linkname reflect_makechan reflect.makechan
 func reflect_makechan(t *chantype, size int64) *hchan {
@@ -44,15 +61,15 @@ func makechan(t *chantype, size int64) *hchan {
                // TODO(dvyukov,rlh): Rethink when collector can move allocated objects.
                c = (*hchan)(mallocgc(hchanSize+uintptr(size)*uintptr(elem.size), nil, flagNoScan))
                if size > 0 && elem.size != 0 {
-                       c.buf = (*uint8)(add(unsafe.Pointer(c), hchanSize))
+                       c.buf = add(unsafe.Pointer(c), hchanSize)
                } else {
                        // race detector uses this location for synchronization
                        // Also prevents us from pointing beyond the allocation (see issue 9401).
-                       c.buf = (*uint8)(unsafe.Pointer(c))
+                       c.buf = unsafe.Pointer(c)
                }
        } else {
                c = new(hchan)
-               c.buf = (*uint8)(newarray(elem, uintptr(size)))
+               c.buf = newarray(elem, uintptr(size))
        }
        c.elemsize = uint16(elem.size)
        c.elemtype = elem
@@ -66,7 +83,7 @@ func makechan(t *chantype, size int64) *hchan {
 
 // chanbuf(c, i) is pointer to the i'th slot in the buffer.
 func chanbuf(c *hchan, i uint) unsafe.Pointer {
-       return add(unsafe.Pointer(c.buf), uintptr(i)*uintptr(c.elemsize))
+       return add(c.buf, uintptr(i)*uintptr(c.elemsize))
 }
 
 // entry point for c <- x from compiled code
diff --git a/src/runtime/chan1.go b/src/runtime/chan1.go
deleted file mode 100644 (file)
index 000775b..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-package runtime
-
-import "unsafe"
-
-//#define      MAXALIGN        8
-
-type waitq struct {
-       first *sudog
-       last  *sudog
-}
-
-type hchan struct {
-       qcount   uint // total data in the q
-       dataqsiz uint // size of the circular q
-       buf      *byte
-       elemsize uint16
-       closed   uint32
-       elemtype *_type // element type
-       sendx    uint   // send index
-       recvx    uint   // receive index
-       recvq    waitq  // list of recv waiters
-       sendq    waitq  // list of send waiters
-       lock     mutex
-}
-
-// Buffer follows Hchan immediately in memory.
-// chanbuf(c, i) is pointer to the i'th slot in the buffer.
-// #define chanbuf(c, i) ((byte*)((c)->buf)+(uintptr)(c)->elemsize*(i))
-
-const (
-       // scase.kind
-       _CaseRecv = iota
-       _CaseSend
-       _CaseDefault
-)
-
-// Known to compiler.
-// Changes here must also be made in src/cmd/gc/select.c's selecttype.
-type scase struct {
-       elem        unsafe.Pointer // data element
-       _chan       *hchan         // chan
-       pc          uintptr        // return pc
-       kind        uint16
-       so          uint16 // vararg of selected bool
-       receivedp   *bool  // pointer to received bool (recv2)
-       releasetime int64
-}
-
-// Known to compiler.
-// Changes here must also be made in src/cmd/gc/select.c's selecttype.
-type _select struct {
-       tcase     uint16   // total count of scase[]
-       ncase     uint16   // currently filled scase[]
-       pollorder *uint16  // case poll order
-       lockorder **hchan  // channel lock order
-       scase     [1]scase // one per case (in order of appearance)
-}
index 34fda16ef890ddb9f475487df44f2003300978bb..db097db3fed10fd711892b2ee9f4221f69886d54 100644 (file)
@@ -10,30 +10,59 @@ import "unsafe"
 
 const (
        debugSelect = false
+
+       // scase.kind
+       caseRecv = iota
+       caseSend
+       caseDefault
 )
 
+// Select statement header.
+// Known to compiler.
+// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
+type hselect struct {
+       tcase     uint16   // total count of scase[]
+       ncase     uint16   // currently filled scase[]
+       pollorder *uint16  // case poll order
+       lockorder **hchan  // channel lock order
+       scase     [1]scase // one per case (in order of appearance)
+}
+
+// Select case descriptor.
+// Known to compiler.
+// Changes here must also be made in src/cmd/internal/gc/select.go's selecttype.
+type scase struct {
+       elem        unsafe.Pointer // data element
+       c           *hchan         // chan
+       pc          uintptr        // return pc
+       kind        uint16
+       so          uint16 // vararg of selected bool
+       receivedp   *bool  // pointer to received bool (recv2)
+       releasetime int64
+}
+
 var (
        chansendpc = funcPC(chansend)
        chanrecvpc = funcPC(chanrecv)
 )
 
 func selectsize(size uintptr) uintptr {
-       selsize := unsafe.Sizeof(_select{}) +
-               (size-1)*unsafe.Sizeof(_select{}.scase[0]) +
-               size*unsafe.Sizeof(*_select{}.lockorder) +
-               size*unsafe.Sizeof(*_select{}.pollorder)
+       selsize := unsafe.Sizeof(hselect{}) +
+               (size-1)*unsafe.Sizeof(hselect{}.scase[0]) +
+               size*unsafe.Sizeof(*hselect{}.lockorder) +
+               size*unsafe.Sizeof(*hselect{}.pollorder)
        return round(selsize, _Int64Align)
 }
 
-func newselect(sel *_select, selsize int64, size int32) {
+func newselect(sel *hselect, selsize int64, size int32) {
        if selsize != int64(selectsize(uintptr(size))) {
                print("runtime: bad select size ", selsize, ", want ", selectsize(uintptr(size)), "\n")
                throw("bad select size")
        }
        sel.tcase = uint16(size)
        sel.ncase = 0
-       sel.lockorder = (**hchan)(add(unsafe.Pointer(&sel.scase), uintptr(size)*unsafe.Sizeof(_select{}.scase[0])))
-       sel.pollorder = (*uint16)(add(unsafe.Pointer(sel.lockorder), uintptr(size)*unsafe.Sizeof(*_select{}.lockorder)))
+       sel.lockorder = (**hchan)(add(unsafe.Pointer(&sel.scase), uintptr(size)*unsafe.Sizeof(hselect{}.scase[0])))
+       sel.pollorder = (*uint16)(add(unsafe.Pointer(sel.lockorder), uintptr(size)*unsafe.Sizeof(*hselect{}.lockorder)))
 
        if debugSelect {
                print("newselect s=", sel, " size=", size, "\n")
@@ -41,7 +70,7 @@ func newselect(sel *_select, selsize int64, size int32) {
 }
 
 //go:nosplit
-func selectsend(sel *_select, c *hchan, elem unsafe.Pointer) (selected bool) {
+func selectsend(sel *hselect, c *hchan, elem unsafe.Pointer) (selected bool) {
        // nil cases do not compete
        if c != nil {
                selectsendImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
@@ -50,7 +79,7 @@ func selectsend(sel *_select, c *hchan, elem unsafe.Pointer) (selected bool) {
 }
 
 // cut in half to give stack a chance to split
-func selectsendImpl(sel *_select, c *hchan, pc uintptr, elem unsafe.Pointer, so uintptr) {
+func selectsendImpl(sel *hselect, c *hchan, pc uintptr, elem unsafe.Pointer, so uintptr) {
        i := sel.ncase
        if i >= sel.tcase {
                throw("selectsend: too many cases")
@@ -59,18 +88,18 @@ func selectsendImpl(sel *_select, c *hchan, pc uintptr, elem unsafe.Pointer, so
        cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
 
        cas.pc = pc
-       cas._chan = c
+       cas.c = c
        cas.so = uint16(so)
-       cas.kind = _CaseSend
+       cas.kind = caseSend
        cas.elem = elem
 
        if debugSelect {
-               print("selectsend s=", sel, " pc=", hex(cas.pc), " chan=", cas._chan, " so=", cas.so, "\n")
+               print("selectsend s=", sel, " pc=", hex(cas.pc), " chan=", cas.c, " so=", cas.so, "\n")
        }
 }
 
 //go:nosplit
-func selectrecv(sel *_select, c *hchan, elem unsafe.Pointer) (selected bool) {
+func selectrecv(sel *hselect, c *hchan, elem unsafe.Pointer) (selected bool) {
        // nil cases do not compete
        if c != nil {
                selectrecvImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, nil, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
@@ -79,7 +108,7 @@ func selectrecv(sel *_select, c *hchan, elem unsafe.Pointer) (selected bool) {
 }
 
 //go:nosplit
-func selectrecv2(sel *_select, c *hchan, elem unsafe.Pointer, received *bool) (selected bool) {
+func selectrecv2(sel *hselect, c *hchan, elem unsafe.Pointer, received *bool) (selected bool) {
        // nil cases do not compete
        if c != nil {
                selectrecvImpl(sel, c, getcallerpc(unsafe.Pointer(&sel)), elem, received, uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
@@ -87,7 +116,7 @@ func selectrecv2(sel *_select, c *hchan, elem unsafe.Pointer, received *bool) (s
        return
 }
 
-func selectrecvImpl(sel *_select, c *hchan, pc uintptr, elem unsafe.Pointer, received *bool, so uintptr) {
+func selectrecvImpl(sel *hselect, c *hchan, pc uintptr, elem unsafe.Pointer, received *bool, so uintptr) {
        i := sel.ncase
        if i >= sel.tcase {
                throw("selectrecv: too many cases")
@@ -95,24 +124,24 @@ func selectrecvImpl(sel *_select, c *hchan, pc uintptr, elem unsafe.Pointer, rec
        sel.ncase = i + 1
        cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
        cas.pc = pc
-       cas._chan = c
+       cas.c = c
        cas.so = uint16(so)
-       cas.kind = _CaseRecv
+       cas.kind = caseRecv
        cas.elem = elem
        cas.receivedp = received
 
        if debugSelect {
-               print("selectrecv s=", sel, " pc=", hex(cas.pc), " chan=", cas._chan, " so=", cas.so, "\n")
+               print("selectrecv s=", sel, " pc=", hex(cas.pc), " chan=", cas.c, " so=", cas.so, "\n")
        }
 }
 
 //go:nosplit
-func selectdefault(sel *_select) (selected bool) {
+func selectdefault(sel *hselect) (selected bool) {
        selectdefaultImpl(sel, getcallerpc(unsafe.Pointer(&sel)), uintptr(unsafe.Pointer(&selected))-uintptr(unsafe.Pointer(&sel)))
        return
 }
 
-func selectdefaultImpl(sel *_select, callerpc uintptr, so uintptr) {
+func selectdefaultImpl(sel *hselect, callerpc uintptr, so uintptr) {
        i := sel.ncase
        if i >= sel.tcase {
                throw("selectdefault: too many cases")
@@ -120,16 +149,16 @@ func selectdefaultImpl(sel *_select, callerpc uintptr, so uintptr) {
        sel.ncase = i + 1
        cas := (*scase)(add(unsafe.Pointer(&sel.scase), uintptr(i)*unsafe.Sizeof(sel.scase[0])))
        cas.pc = callerpc
-       cas._chan = nil
+       cas.c = nil
        cas.so = uint16(so)
-       cas.kind = _CaseDefault
+       cas.kind = caseDefault
 
        if debugSelect {
                print("selectdefault s=", sel, " pc=", hex(cas.pc), " so=", cas.so, "\n")
        }
 }
 
-func sellock(sel *_select) {
+func sellock(sel *hselect) {
        lockslice := sliceStruct{unsafe.Pointer(sel.lockorder), int(sel.ncase), int(sel.ncase)}
        lockorder := *(*[]*hchan)(unsafe.Pointer(&lockslice))
        var c *hchan
@@ -141,7 +170,7 @@ func sellock(sel *_select) {
        }
 }
 
-func selunlock(sel *_select) {
+func selunlock(sel *hselect) {
        // We must be very careful here to not touch sel after we have unlocked
        // the last lock, because sel can be freed right after the last unlock.
        // Consider the following situation.
@@ -168,7 +197,7 @@ func selunlock(sel *_select) {
 }
 
 func selparkcommit(gp *g, sel unsafe.Pointer) bool {
-       selunlock((*_select)(sel))
+       selunlock((*hselect)(sel))
        return true
 }
 
@@ -179,7 +208,7 @@ func block() {
 // overwrites return pc on stack to signal which case of the select
 // to run, so cannot appear at the top of a split stack.
 //go:nosplit
-func selectgo(sel *_select) {
+func selectgo(sel *hselect) {
        pc, offset := selectgoImpl(sel)
        *(*bool)(add(unsafe.Pointer(&sel), uintptr(offset))) = true
        setcallerpc(unsafe.Pointer(&sel), pc)
@@ -187,7 +216,7 @@ func selectgo(sel *_select) {
 
 // selectgoImpl returns scase.pc and scase.so for the select
 // case which fired.
-func selectgoImpl(sel *_select) (uintptr, uint16) {
+func selectgoImpl(sel *hselect) (uintptr, uint16) {
        if debugSelect {
                print("select: sel=", sel, "\n")
        }
@@ -230,7 +259,7 @@ func selectgoImpl(sel *_select) (uintptr, uint16) {
        lockorder := *(*[]*hchan)(unsafe.Pointer(&lockslice))
        for i := 0; i < int(sel.ncase); i++ {
                j := i
-               c := scases[j]._chan
+               c := scases[j].c
                for j > 0 && lockorder[(j-1)/2].sortkey() < c.sortkey() {
                        k := (j - 1) / 2
                        lockorder[j] = lockorder[k]
@@ -287,10 +316,10 @@ loop:
        var cas *scase
        for i := 0; i < int(sel.ncase); i++ {
                cas = &scases[pollorder[i]]
-               c = cas._chan
+               c = cas.c
 
                switch cas.kind {
-               case _CaseRecv:
+               case caseRecv:
                        if c.dataqsiz > 0 {
                                if c.qcount > 0 {
                                        goto asyncrecv
@@ -305,7 +334,7 @@ loop:
                                goto rclose
                        }
 
-               case _CaseSend:
+               case caseSend:
                        if raceenabled {
                                racereadpc(unsafe.Pointer(c), cas.pc, chansendpc)
                        }
@@ -323,7 +352,7 @@ loop:
                                }
                        }
 
-               case _CaseDefault:
+               case caseDefault:
                        dfl = cas
                }
        }
@@ -339,7 +368,7 @@ loop:
        done = 0
        for i := 0; i < int(sel.ncase); i++ {
                cas = &scases[pollorder[i]]
-               c = cas._chan
+               c = cas.c
                sg := acquireSudog()
                sg.g = gp
                // Note: selectdone is adjusted for stack copies in stack.c:adjustsudogs
@@ -353,10 +382,10 @@ loop:
                gp.waiting = sg
 
                switch cas.kind {
-               case _CaseRecv:
+               case caseRecv:
                        c.recvq.enqueue(sg)
 
-               case _CaseSend:
+               case caseSend:
                        c.sendq.enqueue(sg)
                }
        }
@@ -392,8 +421,8 @@ loop:
                        // sg has already been dequeued by the G that woke us up.
                        cas = k
                } else {
-                       c = k._chan
-                       if k.kind == _CaseSend {
+                       c = k.c
+                       if k.kind == caseSend {
                                c.sendq.dequeueSudoG(sglist)
                        } else {
                                c.recvq.dequeueSudoG(sglist)
@@ -409,7 +438,7 @@ loop:
                goto loop
        }
 
-       c = cas._chan
+       c = cas.c
 
        if c.dataqsiz > 0 {
                throw("selectgo: shouldn't happen")
@@ -419,16 +448,16 @@ loop:
                print("wait-return: sel=", sel, " c=", c, " cas=", cas, " kind=", cas.kind, "\n")
        }
 
-       if cas.kind == _CaseRecv {
+       if cas.kind == caseRecv {
                if cas.receivedp != nil {
                        *cas.receivedp = true
                }
        }
 
        if raceenabled {
-               if cas.kind == _CaseRecv && cas.elem != nil {
+               if cas.kind == caseRecv && cas.elem != nil {
                        raceWriteObjectPC(c.elemtype, cas.elem, cas.pc, chanrecvpc)
-               } else if cas.kind == _CaseSend {
+               } else if cas.kind == caseSend {
                        raceReadObjectPC(c.elemtype, cas.elem, cas.pc, chansendpc)
                }
        }
@@ -599,7 +628,7 @@ const (
 func reflect_rselect(cases []runtimeSelect) (chosen int, recvOK bool) {
        // flagNoScan is safe here, because all objects are also referenced from cases.
        size := selectsize(uintptr(len(cases)))
-       sel := (*_select)(mallocgc(size, nil, flagNoScan))
+       sel := (*hselect)(mallocgc(size, nil, flagNoScan))
        newselect(sel, int64(size), int32(len(cases)))
        r := new(bool)
        for i := range cases {