diff options
| author | Cherry Mui <cherryyz@google.com> | 2025-10-03 10:11:20 -0400 |
|---|---|---|
| committer | Cherry Mui <cherryyz@google.com> | 2025-10-03 10:11:21 -0400 |
| commit | fb1749a3fe6ac40c56127d8fcea2e8b13db820e8 (patch) | |
| tree | 72dd38fc84286bf88311850a99e6becf2cbd99bf /src/runtime/testdata/testprog | |
| parent | 703a5fbaad81f1285776bf6f2900506d3c751ea1 (diff) | |
| parent | adce7f196e6ac6d22e9bc851efea5f3ab650947c (diff) | |
| download | go-fb1749a3fe6ac40c56127d8fcea2e8b13db820e8.tar.xz | |
[dev.simd] all: merge master (adce7f1) into dev.simd
Conflicts:
- src/internal/goexperiment/flags.go
- src/runtime/export_test.go
Merge List:
+ 2025-10-03 adce7f196e cmd/link: support .def file with MSVC clang toolchain
+ 2025-10-03 d5b950399d cmd/cgo: fix unaligned arguments typedmemmove crash on iOS
+ 2025-10-02 53845004d6 net/http/httputil: deprecate ReverseProxy.Director
+ 2025-10-02 bbdff9e8e1 net/http: update bundled x/net/http2 and delete obsolete http2inTests
+ 2025-10-02 4008e07080 io/fs: move path name documentation up to the package doc comment
+ 2025-10-02 0e4e2e6832 runtime: skip TestGoroutineLeakProfile under mayMoreStackPreempt
+ 2025-10-02 f03c392295 runtime: fix aix/ppc64 library initialization
+ 2025-10-02 707454b41f cmd/go: update `go help mod edit` with the tool and ignore sections
+ 2025-10-02 8c68a1c1ab runtime,net/http/pprof: goroutine leak detection by using the garbage collector
+ 2025-10-02 84db201ae1 cmd/compile: propagate len([]T{}) to make builtin to allow stack allocation
+ 2025-10-02 5799c139a7 crypto/tls: rm marshalEncryptedClientHelloConfigList dead code
+ 2025-10-01 633dd1d475 encoding/json: fix Decoder.InputOffset regression in goexperiment.jsonv2
+ 2025-10-01 8ad27fb656 doc/go_spec.html: update date
+ 2025-10-01 3f451f2c54 testing/synctest: fix inverted test failure message in TestContextAfterFunc
+ 2025-10-01 be0fed8a5f cmd/go/testdata/script/test_fuzz_fuzztime.txt: disable
+ 2025-09-30 eb1c7f6e69 runtime: move loong64 library entry point to os-agnostic file
+ 2025-09-30 c9257151e5 runtime: unify ppc64/ppc64le library entry point
+ 2025-09-30 4ff8a457db test/codegen: codify handling of floating point constants on arm64
+ 2025-09-30 fcb893fc4b cmd/compile/internal/ssa: remove redundant "type:" prefix check
+ 2025-09-30 19cc1022ba mime: reduce allocs incurred by ParseMediaType
+ 2025-09-30 08afc50bea mime: extend "builtinTypes" to include a more complete list of common types
+ 2025-09-30 97da068774 cmd/compile: eliminate nil checks on .dict arg
+ 2025-09-30 300d9d2714 runtime: initialise debug settings much earlier in startup process
+ 2025-09-30 a846bb0aa5 errors: add AsType
+ 2025-09-30 7c8166d02d cmd/link/internal/arm64: support Mach-O ARM64_RELOC_SUBTRACTOR in internal linking
+ 2025-09-30 6e95748335 cmd/link/internal/arm64: support Mach-O ARM64_RELOC_POINTER_TO_GOT in internal linking
+ 2025-09-30 742f92063e cmd/compile, runtime: always enable Wasm signext and satconv features
+ 2025-09-30 db10db6be3 internal/poll: remove operation fields from FD
+ 2025-09-29 75c87df58e internal/poll: pass the I/O mode instead of an overlapped object in execIO
+ 2025-09-29 fc88e18b4a crypto/internal/fips140/entropy: add CPU jitter-based entropy source
+ 2025-09-29 db4fade759 crypto/internal/fips140/mlkem: make CAST conditional
+ 2025-09-29 db3cb3fd9a runtime: correct reference to getStackMap in comment
+ 2025-09-29 690fc2fb05 internal/poll: remove buf field from operation
+ 2025-09-29 eaf2345256 cmd/link: use a .def file to mark exported symbols on Windows
+ 2025-09-29 4b77733565 internal/syscall/windows: regenerate GetFileSizeEx
+ 2025-09-29 4e9006a716 crypto/tls: quote protocols in ALPN error message
+ 2025-09-29 047c2ab841 cmd/link: don't pass -Wl,-S on Solaris
+ 2025-09-29 ae8eba071b cmd/link: use correct length for pcln.cutab
+ 2025-09-29 fe3ba74b9e cmd/link: skip TestFlagW on platforms without DWARF symbol table
+ 2025-09-29 d42d56b764 encoding/xml: make use of reflect.TypeAssert
+ 2025-09-29 6d51f93257 runtime: jump instead of branch in netbsd/arm64 entry point
+ 2025-09-28 5500cbf0e4 debug/elf: prevent offset overflow
+ 2025-09-27 34e67623a8 all: fix typos
+ 2025-09-27 af6999e60d cmd/compile: implement jump table on loong64
+ 2025-09-26 63cd912083 os/user: simplify go:build
+ 2025-09-26 53009b26dd runtime: use a smaller arena size on Wasm
+ 2025-09-26 3a5df9d2b2 net/http: add HTTP2Config.StrictMaxConcurrentRequests
+ 2025-09-26 16be34df02 net/http: add more tests of transport connection pool
+ 2025-09-26 3e4540b49d os/user: use getgrouplist on illumos && cgo
+ 2025-09-26 15fbe3480b internal/poll: simplify WriteMsg and ReadMsg on Windows
+ 2025-09-26 16ae11a9e1 runtime: move TestReadMetricsSched to testprog
+ 2025-09-26 459f3a3adc cmd/link: don't pass -Wl,-S on AIX
+ 2025-09-26 4631a2d3c6 cmd/link: skip TestFlagW on AIX
+ 2025-09-26 0f31d742cd cmd/compile: fix ICE with new(<untyped expr>)
+ 2025-09-26 7d7cd6e07b internal/poll: don't call SetFilePointerEx in Seek for overlapped handles
+ 2025-09-26 41cba31e66 mime/multipart: percent-encode CR and LF in header values to avoid CRLF injection
+ 2025-09-26 dd1d597c3a Revert "cmd/internal/obj/loong64: use the MOVVP instruction to optimize prologue"
+ 2025-09-26 45d6bc76af runtime: unify arm64 entry point code
+ 2025-09-25 fdea7da3e6 runtime: use common library entry point on windows amd64/386
+ 2025-09-25 e8a4f508d1 lib/fips140: re-seal v1.0.0
+ 2025-09-25 9b7a328089 crypto/internal/fips140: remove key import PCTs, make keygen PCTs fatal
+ 2025-09-25 7f9ab7203f crypto/internal/fips140: update frozen module version to "v1.0.0"
+ 2025-09-25 fb5719cbda crypto/internal/fips140/ecdsa: make TestingOnlyNewDRBG generic
+ 2025-09-25 56067e31f2 std: remove unused declarations
Change-Id: Iecb28fd62c69fbed59da557f46d31bae55889e2c
Diffstat (limited to 'src/runtime/testdata/testprog')
| -rw-r--r-- | src/runtime/testdata/testprog/pipe_unix.go | 15 | ||||
| -rw-r--r-- | src/runtime/testdata/testprog/pipe_windows.go | 13 | ||||
| -rw-r--r-- | src/runtime/testdata/testprog/schedmetrics.go | 267 |
3 files changed, 295 insertions, 0 deletions
diff --git a/src/runtime/testdata/testprog/pipe_unix.go b/src/runtime/testdata/testprog/pipe_unix.go new file mode 100644 index 0000000000..cee4da65f6 --- /dev/null +++ b/src/runtime/testdata/testprog/pipe_unix.go @@ -0,0 +1,15 @@ +// Copyright 2025 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. + +//go:build !windows + +package main + +import "syscall" + +func pipe() (r, w int, err error) { + var p [2]int + err = syscall.Pipe(p[:]) + return p[0], p[1], err +} diff --git a/src/runtime/testdata/testprog/pipe_windows.go b/src/runtime/testdata/testprog/pipe_windows.go new file mode 100644 index 0000000000..597601a179 --- /dev/null +++ b/src/runtime/testdata/testprog/pipe_windows.go @@ -0,0 +1,13 @@ +// Copyright 2025 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 main + +import "syscall" + +func pipe() (r, w syscall.Handle, err error) { + var p [2]syscall.Handle + err = syscall.Pipe(p[:]) + return p[0], p[1], err +} diff --git a/src/runtime/testdata/testprog/schedmetrics.go b/src/runtime/testdata/testprog/schedmetrics.go new file mode 100644 index 0000000000..6d3f68a848 --- /dev/null +++ b/src/runtime/testdata/testprog/schedmetrics.go @@ -0,0 +1,267 @@ +// Copyright 2025 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 main + +import ( + "bytes" + "fmt" + "internal/testenv" + "log" + "os" + "runtime" + "runtime/debug" + "runtime/metrics" + "strings" + "sync/atomic" + "syscall" + "time" +) + +func init() { + register("SchedMetrics", SchedMetrics) +} + +// Tests runtime/metrics.Read for various scheduler metrics. +// +// Implemented in testprog to prevent other tests from polluting +// the metrics. +func SchedMetrics() { + const ( + notInGo = iota + runnable + running + waiting + created + threads + numSamples + ) + var s [numSamples]metrics.Sample + s[notInGo].Name = "/sched/goroutines/not-in-go:goroutines" + s[runnable].Name = "/sched/goroutines/runnable:goroutines" + s[running].Name = "/sched/goroutines/running:goroutines" + s[waiting].Name = "/sched/goroutines/waiting:goroutines" + s[created].Name = "/sched/goroutines-created:goroutines" + s[threads].Name = "/sched/threads/total:threads" + + var failed bool + var out bytes.Buffer + logger := log.New(&out, "", 0) + indent := 0 + logf := func(s string, a ...any) { + var prefix strings.Builder + for range indent { + prefix.WriteString("\t") + } + logger.Printf(prefix.String()+s, a...) + } + errorf := func(s string, a ...any) { + logf(s, a...) + failed = true + } + run := func(name string, f func()) { + logf("=== Checking %q", name) + indent++ + f() + indent-- + } + logMetrics := func(s []metrics.Sample) { + for i := range s { + logf("%s: %d", s[i].Name, s[i].Value.Uint64()) + } + } + + // generalSlack is the amount of goroutines we allow ourselves to be + // off by in any given category, either due to background system + // goroutines. This excludes GC goroutines. + generalSlack := uint64(4) + + // waitingSlack is the max number of blocked goroutines controlled + // by the runtime that we'll allow for. This includes GC goroutines + // as well as finalizer and cleanup goroutines. + waitingSlack := generalSlack + uint64(2*runtime.GOMAXPROCS(-1)) + + // threadsSlack is the maximum number of threads left over + // from the runtime (sysmon, the template thread, etc.) + const threadsSlack = 4 + + // Make sure GC isn't running, since GC workers interfere with + // expected counts. + defer debug.SetGCPercent(debug.SetGCPercent(-1)) + runtime.GC() + + check := func(s *metrics.Sample, min, max uint64) { + val := s.Value.Uint64() + if val < min { + errorf("%s too low; %d < %d", s.Name, val, min) + } + if val > max { + errorf("%s too high; %d > %d", s.Name, val, max) + } + } + checkEq := func(s *metrics.Sample, value uint64) { + check(s, value, value) + } + spinUntil := func(f func() bool) bool { + for { + if f() { + return true + } + time.Sleep(50 * time.Millisecond) + } + } + + // Check base values. + run("base", func() { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) + metrics.Read(s[:]) + logMetrics(s[:]) + check(&s[notInGo], 0, generalSlack) + check(&s[runnable], 0, generalSlack) + checkEq(&s[running], 1) + check(&s[waiting], 0, waitingSlack) + }) + + metrics.Read(s[:]) + createdAfterBase := s[created].Value.Uint64() + + // Force Running count to be high. We'll use these goroutines + // for Runnable, too. + const count = 10 + var ready, exit atomic.Uint32 + for range count { + go func() { + ready.Add(1) + for exit.Load() == 0 { + // Spin to get us and keep us running, but check + // the exit condition so we exit out early if we're + // done. + start := time.Now() + for time.Since(start) < 10*time.Millisecond && exit.Load() == 0 { + } + runtime.Gosched() + } + }() + } + for ready.Load() < count { + runtime.Gosched() + } + + // Be careful. We've entered a dangerous state for platforms + // that do not return back to the underlying system unless all + // goroutines are blocked, like js/wasm, since we have a bunch + // of runnable goroutines all spinning. We cannot write anything + // out. + if testenv.HasParallelism() { + run("created", func() { + metrics.Read(s[:]) + logMetrics(s[:]) + checkEq(&s[created], createdAfterBase+count) + }) + run("running", func() { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(count + 4)) + // It can take a little bit for the scheduler to + // distribute the goroutines to Ps, so retry until + // we see the count we expect or the test times out. + spinUntil(func() bool { + metrics.Read(s[:]) + return s[running].Value.Uint64() >= count + }) + logMetrics(s[:]) + check(&s[running], count, count+4) + check(&s[threads], count, count+4+threadsSlack) + }) + + // Force runnable count to be high. + run("runnable", func() { + defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1)) + metrics.Read(s[:]) + logMetrics(s[:]) + checkEq(&s[running], 1) + check(&s[runnable], count-1, count+generalSlack) + }) + + // Done with the running/runnable goroutines. + exit.Store(1) + } else { + // Read metrics and then exit all the other goroutines, + // so that system calls may proceed. + metrics.Read(s[:]) + + // Done with the running/runnable goroutines. + exit.Store(1) + + // Now we can check our invariants. + run("created", func() { + // Look for count-1 goroutines because we read metrics + // *before* run goroutine was created for this sub-test. + checkEq(&s[created], createdAfterBase+count-1) + }) + run("running", func() { + logMetrics(s[:]) + checkEq(&s[running], 1) + checkEq(&s[threads], 1) + }) + run("runnable", func() { + logMetrics(s[:]) + check(&s[runnable], count-1, count+generalSlack) + }) + } + + // Force not-in-go count to be high. This is a little tricky since + // we try really hard not to let things block in system calls. + // We have to drop to the syscall package to do this reliably. + run("not-in-go", func() { + // Block a bunch of goroutines on an OS pipe. + pr, pw, err := pipe() + if err != nil { + switch runtime.GOOS { + case "js", "wasip1": + logf("creating pipe: %v", err) + return + } + panic(fmt.Sprintf("creating pipe: %v", err)) + } + for i := 0; i < count; i++ { + go syscall.Read(pr, make([]byte, 1)) + } + + // Let the goroutines block. + spinUntil(func() bool { + metrics.Read(s[:]) + return s[notInGo].Value.Uint64() >= count + }) + logMetrics(s[:]) + check(&s[notInGo], count, count+generalSlack) + + syscall.Close(pw) + syscall.Close(pr) + }) + + run("waiting", func() { + // Force waiting count to be high. + const waitingCount = 1000 + stop := make(chan bool) + for i := 0; i < waitingCount; i++ { + go func() { <-stop }() + } + + // Let the goroutines block. + spinUntil(func() bool { + metrics.Read(s[:]) + return s[waiting].Value.Uint64() >= waitingCount + }) + logMetrics(s[:]) + check(&s[waiting], waitingCount, waitingCount+waitingSlack) + + close(stop) + }) + + if failed { + fmt.Fprintln(os.Stderr, out.String()) + os.Exit(1) + } else { + fmt.Fprintln(os.Stderr, "OK") + } +} |
