Commit 1d8fa7fa authored by Keith Randall's avatar Keith Randall

runtime: convert select implementation to Go.

LGTM=rsc
R=golang-codereviews, bradfitz, iant, khr, rsc
CC=golang-codereviews
https://golang.org/cl/139020043
parent 86040a09
......@@ -403,6 +403,7 @@ func (w *Walker) parseFile(dir, file string) (*ast.File, error) {
" sudog struct{};" +
" waitq struct{};" +
" wincallbackcontext struct{};" +
" _select struct{}; " +
"); " +
"const ( cb_max = 2000 )"
f, err = parser.ParseFile(fset, filename, src, 0)
......
......@@ -347,12 +347,13 @@ selecttype(int32 size)
sudog->type->local = 1;
scase = nod(OTSTRUCT, N, N);
scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("sg")), sudog));
scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("elem")), typenod(ptrto(types[TUINT8]))));
scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("chan")), typenod(ptrto(types[TUINT8]))));
scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("pc")), typenod(types[TUINTPTR])));
scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("kind")), typenod(types[TUINT16])));
scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("so")), typenod(types[TUINT16])));
scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("receivedp")), typenod(ptrto(types[TUINT8]))));
scase->list = list(scase->list, nod(ODCLFIELD, newname(lookup("releasetime")), typenod(types[TUINT64])));
typecheck(&scase, Etype);
scase->type->noalg = 1;
scase->type->local = 1;
......
......@@ -2073,7 +2073,7 @@ func Copy(dst, src Value) int {
}
// A runtimeSelect is a single case passed to rselect.
// This must match ../runtime/chan.c:/runtimeSelect
// This must match ../runtime/select.go:/runtimeSelect
type runtimeSelect struct {
dir uintptr // 0, SendDir, or RecvDir
typ *rtype // channel type
......@@ -2091,7 +2091,7 @@ func rselect([]runtimeSelect) (chosen int, recvOK bool)
// A SelectDir describes the communication direction of a select case.
type SelectDir int
// NOTE: These values must match ../runtime/chan.c:/SelectDir.
// NOTE: These values must match ../runtime/select.go:/selectDir.
const (
_ SelectDir = iota
......
......@@ -4,8 +4,7 @@
package runtime
// This file contains the implementation of Go channels
// and select statements.
// This file contains the implementation of Go channels.
import "unsafe"
......
This diff is collapsed.
......@@ -47,12 +47,13 @@ enum
// Changes here must also be made in src/cmd/gc/select.c's selecttype.
struct Scase
{
SudoG sg; // must be first member (cast to Scase)
void* elem; // data element
Hchan* chan; // chan
byte* pc; // return pc
uintptr pc; // return pc
uint16 kind;
uint16 so; // vararg of selected bool
bool* receivedp; // pointer to received bool (recv2)
int64 releasetime;
};
// Known to compiler.
......
......@@ -328,13 +328,13 @@ func TestBlockProfile(t *testing.T) {
`},
{"select recv async", blockSelectRecvAsync, `
[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
# 0x[0-9,a-f]+ runtime\.selectgo\+0x[0-9,a-f]+ .*/src/pkg/runtime/chan.goc:[0-9]+
# 0x[0-9,a-f]+ runtime\.selectgo\+0x[0-9,a-f]+ .*/src/pkg/runtime/select.go:[0-9]+
# 0x[0-9,a-f]+ runtime/pprof_test\.blockSelectRecvAsync\+0x[0-9,a-f]+ .*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
# 0x[0-9,a-f]+ runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+ .*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
`},
{"select send sync", blockSelectSendSync, `
[0-9]+ [0-9]+ @ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+ 0x[0-9,a-f]+
# 0x[0-9,a-f]+ runtime\.selectgo\+0x[0-9,a-f]+ .*/src/pkg/runtime/chan.goc:[0-9]+
# 0x[0-9,a-f]+ runtime\.selectgo\+0x[0-9,a-f]+ .*/src/pkg/runtime/select.go:[0-9]+
# 0x[0-9,a-f]+ runtime/pprof_test\.blockSelectSendSync\+0x[0-9,a-f]+ .*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
# 0x[0-9,a-f]+ runtime/pprof_test\.TestBlockProfile\+0x[0-9,a-f]+ .*/src/pkg/runtime/pprof/pprof_test.go:[0-9]+
`},
......
......@@ -45,3 +45,16 @@ func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
racereadpc(addr, callerpc, pc)
}
}
func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
kind := t.kind & kindMask
if kind == kindArray || kind == kindStruct {
// for composite objects we have to write every address
// because a write might happen to any subobject.
racewriterangepc(addr, int(t.size), callerpc, pc)
} else {
// for non-composite objects we can write just the start
// address, as any write must write the first byte.
racewritepc(addr, callerpc, pc)
}
}
......@@ -16,3 +16,5 @@ const raceenabled = false
func raceReadObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
}
func raceWriteObjectPC(t *_type, addr unsafe.Pointer, callerpc, pc uintptr) {
}
This diff is collapsed.
......@@ -764,6 +764,9 @@ adjustsudogs(G *gp, AdjustInfo *adjinfo)
e = s->elem;
if(adjinfo->oldstk <= e && e < adjinfo->oldbase)
s->elem = e + adjinfo->delta;
e = (byte*)s->selectdone;
if(adjinfo->oldstk <= e && e < adjinfo->oldbase)
s->selectdone = (uint32*)(e + adjinfo->delta);
}
}
......
......@@ -115,3 +115,6 @@ TEXT reflect·unsafe_NewArray(SB),NOSPLIT,$0-0
TEXT reflect·makechan(SB),NOSPLIT,$0-0
JMP runtime·makechan(SB)
TEXT reflect·rselect(SB), NOSPLIT, $0-0
JMP runtime·reflect_rselect(SB)
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment