go/ssa/interp: add intrinsic for runtime.NumGoroutine

...which is used by $GOROOT/test/goprint.go.

Change-Id: I4626b8fae3f87d9c8dd8cdcd8c05036955a36262
Reviewed-on: https://go-review.googlesource.com/22560
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Alan Donovan 2016-04-28 13:44:44 -04:00
parent 50ff896a1c
commit 56005b4126
2 changed files with 18 additions and 5 deletions

View File

@ -15,6 +15,7 @@ import (
"os"
"runtime"
"strings"
"sync/atomic"
"syscall"
"time"
"unsafe"
@ -104,6 +105,7 @@ func init() {
"runtime.Gosched": ext۰runtime۰Gosched,
"runtime.init": ext۰runtime۰init,
"runtime.NumCPU": ext۰runtime۰NumCPU,
"runtime.NumGoroutine": ext۰runtime۰NumGoroutine,
"runtime.ReadMemStats": ext۰runtime۰ReadMemStats,
"runtime.SetFinalizer": ext۰runtime۰SetFinalizer,
"(*runtime.Func).Entry": ext۰runtime۰Func۰Entry,
@ -387,6 +389,10 @@ func ext۰runtime۰NumCPU(fr *frame, args []value) value {
return runtime.NumCPU()
}
func ext۰runtime۰NumGoroutine(fr *frame, args []value) value {
return int(atomic.LoadInt32(&fr.i.goroutines))
}
func ext۰runtime۰ReadMemStats(fr *frame, args []value) value {
// TODO(adonovan): populate args[0].(Struct)
return nil

View File

@ -53,6 +53,7 @@ import (
"os"
"reflect"
"runtime"
"sync/atomic"
"golang.org/x/tools/go/ssa"
)
@ -86,6 +87,7 @@ type interpreter struct {
rtypeMethods methodSet // the method set of rtype, which implements the reflect.Type interface.
runtimeErrorString types.Type // the runtime.errorString type
sizes types.Sizes // the effective type-sizing function
goroutines int32 // atomically updated
}
type deferred struct {
@ -269,7 +271,11 @@ func visitInstr(fr *frame, instr ssa.Instruction) continuation {
case *ssa.Go:
fn, args := prepareCall(fr, &instr.Call)
go call(fr.i, nil, instr.Pos(), fn, args)
atomic.AddInt32(&fr.i.goroutines, 1)
go func() {
call(fr.i, nil, instr.Pos(), fn, args)
atomic.AddInt32(&fr.i.goroutines, -1)
}()
case *ssa.MakeChan:
fr.env[instr] = make(chan value, asInt(fr.get(instr.Size)))
@ -660,10 +666,11 @@ func deleteBodies(pkg *ssa.Package, except ...string) {
//
func Interpret(mainpkg *ssa.Package, mode Mode, sizes types.Sizes, filename string, args []string) (exitCode int) {
i := &interpreter{
prog: mainpkg.Prog,
globals: make(map[ssa.Value]*value),
mode: mode,
sizes: sizes,
prog: mainpkg.Prog,
globals: make(map[ssa.Value]*value),
mode: mode,
sizes: sizes,
goroutines: 1,
}
runtimePkg := i.prog.ImportedPackage("runtime")
if runtimePkg == nil {