summaryrefslogtreecommitdiffstats
path: root/llgo/third_party/gofrontend/libgo/go/runtime/proc_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'llgo/third_party/gofrontend/libgo/go/runtime/proc_test.go')
-rw-r--r--llgo/third_party/gofrontend/libgo/go/runtime/proc_test.go137
1 files changed, 137 insertions, 0 deletions
diff --git a/llgo/third_party/gofrontend/libgo/go/runtime/proc_test.go b/llgo/third_party/gofrontend/libgo/go/runtime/proc_test.go
index 4f364dc4636..4350e8f89d2 100644
--- a/llgo/third_party/gofrontend/libgo/go/runtime/proc_test.go
+++ b/llgo/third_party/gofrontend/libgo/go/runtime/proc_test.go
@@ -7,6 +7,8 @@ package runtime_test
import (
"math"
"runtime"
+ "runtime/debug"
+ "sync"
"sync/atomic"
"syscall"
"testing"
@@ -94,6 +96,10 @@ func TestYieldLocked(t *testing.T) {
}
func TestGoroutineParallelism(t *testing.T) {
+ if runtime.NumCPU() == 1 {
+ // Takes too long, too easy to deadlock, etc.
+ t.Skip("skipping on uniprocessor")
+ }
P := 4
N := 10
if testing.Short() {
@@ -101,6 +107,10 @@ func TestGoroutineParallelism(t *testing.T) {
N = 3
}
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(P))
+ // If runtime triggers a forced GC during this test then it will deadlock,
+ // since the goroutines can't be stopped/preempted.
+ // Disable GC for this test (see issue #10958).
+ defer debug.SetGCPercent(debug.SetGCPercent(-1))
for try := 0; try < N; try++ {
done := make(chan bool)
x := uint32(0)
@@ -289,6 +299,98 @@ func main() {
}
`
+func TestPingPongHog(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in -short mode")
+ }
+
+ defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+ done := make(chan bool)
+ hogChan, lightChan := make(chan bool), make(chan bool)
+ hogCount, lightCount := 0, 0
+
+ run := func(limit int, counter *int, wake chan bool) {
+ for {
+ select {
+ case <-done:
+ return
+
+ case <-wake:
+ for i := 0; i < limit; i++ {
+ *counter++
+ }
+ wake <- true
+ }
+ }
+ }
+
+ // Start two co-scheduled hog goroutines.
+ for i := 0; i < 2; i++ {
+ go run(1e6, &hogCount, hogChan)
+ }
+
+ // Start two co-scheduled light goroutines.
+ for i := 0; i < 2; i++ {
+ go run(1e3, &lightCount, lightChan)
+ }
+
+ // Start goroutine pairs and wait for a few preemption rounds.
+ hogChan <- true
+ lightChan <- true
+ time.Sleep(100 * time.Millisecond)
+ close(done)
+ <-hogChan
+ <-lightChan
+
+ // Check that hogCount and lightCount are within a factor of
+ // 2, which indicates that both pairs of goroutines handed off
+ // the P within a time-slice to their buddy.
+ if hogCount > lightCount*2 || lightCount > hogCount*2 {
+ t.Fatalf("want hogCount/lightCount in [0.5, 2]; got %d/%d = %g", hogCount, lightCount, float64(hogCount)/float64(lightCount))
+ }
+}
+
+func BenchmarkPingPongHog(b *testing.B) {
+ defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
+
+ // Create a CPU hog
+ stop, done := make(chan bool), make(chan bool)
+ go func() {
+ for {
+ select {
+ case <-stop:
+ done <- true
+ return
+ default:
+ }
+ }
+ }()
+
+ // Ping-pong b.N times
+ ping, pong := make(chan bool), make(chan bool)
+ go func() {
+ for j := 0; j < b.N; j++ {
+ pong <- <-ping
+ }
+ close(stop)
+ done <- true
+ }()
+ go func() {
+ for i := 0; i < b.N; i++ {
+ ping <- <-pong
+ }
+ done <- true
+ }()
+ b.ResetTimer()
+ ping <- true // Start ping-pong
+ <-stop
+ b.StopTimer()
+ <-ping // Let last ponger exit
+ <-done // Make sure goroutines exit
+ <-done
+ <-done
+}
+
func stackGrowthRecursive(i int) {
var pad [128]uint64
if i != 0 && pad[0] == 0 {
@@ -364,13 +466,17 @@ func nonleaf(stop chan int) bool {
}
}
+/*
func TestSchedLocalQueue(t *testing.T) {
runtime.TestSchedLocalQueue1()
}
+*/
+/*
func TestSchedLocalQueueSteal(t *testing.T) {
runtime.TestSchedLocalQueueSteal1()
}
+*/
func benchmarkStackGrowth(b *testing.B, rec int) {
b.RunParallel(func(pb *testing.PB) {
@@ -414,6 +520,37 @@ func benchmarkCreateGoroutines(b *testing.B, procs int) {
}
}
+func BenchmarkCreateGoroutinesCapture(b *testing.B) {
+ b.ReportAllocs()
+ for i := 0; i < b.N; i++ {
+ const N = 4
+ var wg sync.WaitGroup
+ wg.Add(N)
+ for i := 0; i < N; i++ {
+ i := i
+ go func() {
+ if i >= N {
+ b.Logf("bad") // just to capture b
+ }
+ wg.Done()
+ }()
+ }
+ wg.Wait()
+ }
+}
+
+func BenchmarkClosureCall(b *testing.B) {
+ sum := 0
+ off1 := 1
+ for i := 0; i < b.N; i++ {
+ off2 := 2
+ func() {
+ sum += i + off1 + off2
+ }()
+ }
+ _ = sum
+}
+
type Matrix [][]float64
func BenchmarkMatmult(b *testing.B) {
OpenPOWER on IntegriCloud