Commit 17584929 authored by Gustavo Niemeyer's avatar Gustavo Niemeyer

runtime: fix pseudo-randomness on some selects

Fixes #2152.

R=golang-dev, dvyukov
CC=golang-dev
https://golang.org/cl/4888044
parent d7440ce2
...@@ -904,7 +904,8 @@ loop: ...@@ -904,7 +904,8 @@ loop:
// pass 2 - enqueue on all chans // pass 2 - enqueue on all chans
for(i=0; i<sel->ncase; i++) { for(i=0; i<sel->ncase; i++) {
cas = &sel->scase[i]; o = sel->pollorder[i];
cas = &sel->scase[o];
c = cas->chan; c = cas->chan;
sg = &cas->sg; sg = &cas->sg;
sg->g = g; sg->g = g;
......
...@@ -6,6 +6,7 @@ package runtime_test ...@@ -6,6 +6,7 @@ package runtime_test
import ( import (
"runtime" "runtime"
"sync"
"sync/atomic" "sync/atomic"
"testing" "testing"
) )
...@@ -26,6 +27,38 @@ func TestChanSendInterface(t *testing.T) { ...@@ -26,6 +27,38 @@ func TestChanSendInterface(t *testing.T) {
} }
} }
func TestPseudoRandomSend(t *testing.T) {
n := 100
c := make(chan int)
l := make([]int, n)
var m sync.Mutex
m.Lock()
go func() {
for i := 0; i < n; i++ {
runtime.Gosched()
l[i] = <-c
}
m.Unlock()
}()
for i := 0; i < n; i++ {
select {
case c <- 0:
case c <- 1:
}
}
m.Lock() // wait
n0 := 0
n1 := 0
for _, i := range l {
n0 += (i + 1) % 2
n1 += i
if n0 > n/10 && n1 > n/10 {
return
}
}
t.Errorf("Want pseudo random, got %d zeros and %d ones", n0, n1)
}
func BenchmarkSelectUncontended(b *testing.B) { func BenchmarkSelectUncontended(b *testing.B) {
const CallsPerSched = 1000 const CallsPerSched = 1000
procs := runtime.GOMAXPROCS(-1) procs := runtime.GOMAXPROCS(-1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment