runtime: ensure fair scheduling during frequent GCs

What was happenning is as follows:
Each writer goroutine always triggers GC during its scheduling quntum.
After GC goroutines are shuffled so that the timer goroutine is always second in the queue.
This repeats infinitely, causing timer goroutine starvation.
Fixes #7126.

R=golang-codereviews, shanemhansen, khr, khr
CC=golang-codereviews
https://golang.org/cl/53080043
This commit is contained in:
Dmitriy Vyukov 2014-01-21 10:24:42 +04:00
parent cfb9cf0f06
commit 90eca36a23
2 changed files with 65 additions and 5 deletions

View file

@ -244,6 +244,49 @@ func TestPreemptionGC(t *testing.T) {
atomic.StoreUint32(&stop, 1)
}
func TestGCFairness(t *testing.T) {
output := executeTest(t, testGCFairnessSource, nil)
want := "OK\n"
if output != want {
t.Fatalf("want %s, got %s\n", want, output)
}
}
const testGCFairnessSource = `
package main
import (
"fmt"
"os"
"runtime"
"time"
)
func main() {
runtime.GOMAXPROCS(1)
f, err := os.Open("/dev/null")
if os.IsNotExist(err) {
// This test tests what it is intended to test only if writes are fast.
// If there is no /dev/null, we just don't execute the test.
fmt.Println("OK\n")
return
}
if err != nil {
fmt.Println(err)
os.Exit(1)
}
for i := 0; i < 2; i++ {
go func() {
for {
f.Write([]byte("."))
}
}()
}
time.Sleep(10 * time.Millisecond)
fmt.Println("OK")
}
`
func stackGrowthRecursive(i int) {
var pad [128]uint64
if i != 0 && pad[0] == 0 {