summaryrefslogtreecommitdiff
path: root/libgo/go/runtime/testdata/testprog/gc.go
diff options
context:
space:
mode:
Diffstat (limited to 'libgo/go/runtime/testdata/testprog/gc.go')
-rw-r--r--libgo/go/runtime/testdata/testprog/gc.go37
1 files changed, 36 insertions, 1 deletions
diff --git a/libgo/go/runtime/testdata/testprog/gc.go b/libgo/go/runtime/testdata/testprog/gc.go
index 9bb367c0d15..a0c1f82b56b 100644
--- a/libgo/go/runtime/testdata/testprog/gc.go
+++ b/libgo/go/runtime/testdata/testprog/gc.go
@@ -1,4 +1,4 @@
-// Copyright 2015 The Go Authors. All rights reserved.
+// Copyright 2015 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.
@@ -8,11 +8,14 @@ import (
"fmt"
"os"
"runtime"
+ "runtime/debug"
+ "sync/atomic"
"time"
)
func init() {
register("GCFairness", GCFairness)
+ register("GCFairness2", GCFairness2)
register("GCSys", GCSys)
}
@@ -72,3 +75,35 @@ func GCFairness() {
time.Sleep(10 * time.Millisecond)
fmt.Println("OK")
}
+
+func GCFairness2() {
+ // Make sure user code can't exploit the GC's high priority
+ // scheduling to make scheduling of user code unfair. See
+ // issue #15706.
+ runtime.GOMAXPROCS(1)
+ debug.SetGCPercent(1)
+ var count [3]int64
+ var sink [3]interface{}
+ for i := range count {
+ go func(i int) {
+ for {
+ sink[i] = make([]byte, 1024)
+ atomic.AddInt64(&count[i], 1)
+ }
+ }(i)
+ }
+ // Note: If the unfairness is really bad, it may not even get
+ // past the sleep.
+ //
+ // If the scheduling rules change, this may not be enough time
+ // to let all goroutines run, but for now we cycle through
+ // them rapidly.
+ time.Sleep(30 * time.Millisecond)
+ for i := range count {
+ if atomic.LoadInt64(&count[i]) == 0 {
+ fmt.Printf("goroutine %d did not run\n", i)
+ return
+ }
+ }
+ fmt.Println("OK")
+}