Initial commit: Go 1.23 release state
This commit is contained in:
331
test/ken/chan.go
Normal file
331
test/ken/chan.go
Normal file
@@ -0,0 +1,331 @@
|
||||
// run
|
||||
|
||||
// Copyright 2009 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.
|
||||
|
||||
// Test communication operations including select.
|
||||
|
||||
package main
|
||||
|
||||
import "os"
|
||||
import "runtime"
|
||||
import "sync"
|
||||
|
||||
var randx int
|
||||
|
||||
func nrand(n int) int {
|
||||
randx += 10007
|
||||
if randx >= 1000000 {
|
||||
randx -= 1000000
|
||||
}
|
||||
return randx % n
|
||||
}
|
||||
|
||||
type Chan struct {
|
||||
sc, rc chan int // send and recv chan
|
||||
sv, rv int // send and recv seq
|
||||
}
|
||||
|
||||
var (
|
||||
nproc int
|
||||
nprocLock sync.Mutex
|
||||
cval int
|
||||
end int = 10000
|
||||
totr, tots int
|
||||
totLock sync.Mutex
|
||||
nc *Chan
|
||||
)
|
||||
|
||||
func init() {
|
||||
nc = new(Chan)
|
||||
}
|
||||
|
||||
func changeNproc(adjust int) int {
|
||||
nprocLock.Lock()
|
||||
nproc += adjust
|
||||
ret := nproc
|
||||
nprocLock.Unlock()
|
||||
return ret
|
||||
}
|
||||
|
||||
func mkchan(c, n int) []*Chan {
|
||||
ca := make([]*Chan, n)
|
||||
for i := 0; i < n; i++ {
|
||||
cval = cval + 100
|
||||
ch := new(Chan)
|
||||
ch.sc = make(chan int, c)
|
||||
ch.rc = ch.sc
|
||||
ch.sv = cval
|
||||
ch.rv = cval
|
||||
ca[i] = ch
|
||||
}
|
||||
return ca
|
||||
}
|
||||
|
||||
func expect(v, v0 int) (newv int) {
|
||||
if v == v0 {
|
||||
if v%100 == 75 {
|
||||
return end
|
||||
}
|
||||
return v + 1
|
||||
}
|
||||
print("got ", v, " expected ", v0+1, "\n")
|
||||
panic("fail")
|
||||
}
|
||||
|
||||
func (c *Chan) send() bool {
|
||||
// print("send ", c.sv, "\n");
|
||||
totLock.Lock()
|
||||
tots++
|
||||
totLock.Unlock()
|
||||
c.sv = expect(c.sv, c.sv)
|
||||
if c.sv == end {
|
||||
c.sc = nil
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func send(c *Chan) {
|
||||
for {
|
||||
for r := nrand(10); r >= 0; r-- {
|
||||
runtime.Gosched()
|
||||
}
|
||||
c.sc <- c.sv
|
||||
if c.send() {
|
||||
break
|
||||
}
|
||||
}
|
||||
changeNproc(-1)
|
||||
}
|
||||
|
||||
func (c *Chan) recv(v int) bool {
|
||||
// print("recv ", v, "\n");
|
||||
totLock.Lock()
|
||||
totr++
|
||||
totLock.Unlock()
|
||||
c.rv = expect(c.rv, v)
|
||||
if c.rv == end {
|
||||
c.rc = nil
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func recv(c *Chan) {
|
||||
var v int
|
||||
|
||||
for {
|
||||
for r := nrand(10); r >= 0; r-- {
|
||||
runtime.Gosched()
|
||||
}
|
||||
v = <-c.rc
|
||||
if c.recv(v) {
|
||||
break
|
||||
}
|
||||
}
|
||||
changeNproc(-1)
|
||||
}
|
||||
|
||||
func sel(r0, r1, r2, r3, s0, s1, s2, s3 *Chan) {
|
||||
var v int
|
||||
|
||||
a := 0 // local chans running
|
||||
|
||||
if r0.rc != nil {
|
||||
a++
|
||||
}
|
||||
if r1.rc != nil {
|
||||
a++
|
||||
}
|
||||
if r2.rc != nil {
|
||||
a++
|
||||
}
|
||||
if r3.rc != nil {
|
||||
a++
|
||||
}
|
||||
if s0.sc != nil {
|
||||
a++
|
||||
}
|
||||
if s1.sc != nil {
|
||||
a++
|
||||
}
|
||||
if s2.sc != nil {
|
||||
a++
|
||||
}
|
||||
if s3.sc != nil {
|
||||
a++
|
||||
}
|
||||
|
||||
for {
|
||||
for r := nrand(5); r >= 0; r-- {
|
||||
runtime.Gosched()
|
||||
}
|
||||
|
||||
select {
|
||||
case v = <-r0.rc:
|
||||
if r0.recv(v) {
|
||||
a--
|
||||
}
|
||||
case v = <-r1.rc:
|
||||
if r1.recv(v) {
|
||||
a--
|
||||
}
|
||||
case v = <-r2.rc:
|
||||
if r2.recv(v) {
|
||||
a--
|
||||
}
|
||||
case v = <-r3.rc:
|
||||
if r3.recv(v) {
|
||||
a--
|
||||
}
|
||||
case s0.sc <- s0.sv:
|
||||
if s0.send() {
|
||||
a--
|
||||
}
|
||||
case s1.sc <- s1.sv:
|
||||
if s1.send() {
|
||||
a--
|
||||
}
|
||||
case s2.sc <- s2.sv:
|
||||
if s2.send() {
|
||||
a--
|
||||
}
|
||||
case s3.sc <- s3.sv:
|
||||
if s3.send() {
|
||||
a--
|
||||
}
|
||||
}
|
||||
if a == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
changeNproc(-1)
|
||||
}
|
||||
|
||||
// direct send to direct recv
|
||||
func test1(c *Chan) {
|
||||
changeNproc(2)
|
||||
go send(c)
|
||||
go recv(c)
|
||||
}
|
||||
|
||||
// direct send to select recv
|
||||
func test2(c int) {
|
||||
ca := mkchan(c, 4)
|
||||
|
||||
changeNproc(4)
|
||||
go send(ca[0])
|
||||
go send(ca[1])
|
||||
go send(ca[2])
|
||||
go send(ca[3])
|
||||
|
||||
changeNproc(1)
|
||||
go sel(ca[0], ca[1], ca[2], ca[3], nc, nc, nc, nc)
|
||||
}
|
||||
|
||||
// select send to direct recv
|
||||
func test3(c int) {
|
||||
ca := mkchan(c, 4)
|
||||
|
||||
changeNproc(4)
|
||||
go recv(ca[0])
|
||||
go recv(ca[1])
|
||||
go recv(ca[2])
|
||||
go recv(ca[3])
|
||||
|
||||
changeNproc(1)
|
||||
go sel(nc, nc, nc, nc, ca[0], ca[1], ca[2], ca[3])
|
||||
}
|
||||
|
||||
// select send to select recv
|
||||
func test4(c int) {
|
||||
ca := mkchan(c, 4)
|
||||
|
||||
changeNproc(2)
|
||||
go sel(nc, nc, nc, nc, ca[0], ca[1], ca[2], ca[3])
|
||||
go sel(ca[0], ca[1], ca[2], ca[3], nc, nc, nc, nc)
|
||||
}
|
||||
|
||||
func test5(c int) {
|
||||
ca := mkchan(c, 8)
|
||||
|
||||
changeNproc(2)
|
||||
go sel(ca[4], ca[5], ca[6], ca[7], ca[0], ca[1], ca[2], ca[3])
|
||||
go sel(ca[0], ca[1], ca[2], ca[3], ca[4], ca[5], ca[6], ca[7])
|
||||
}
|
||||
|
||||
func test6(c int) {
|
||||
ca := mkchan(c, 12)
|
||||
|
||||
changeNproc(4)
|
||||
go send(ca[4])
|
||||
go send(ca[5])
|
||||
go send(ca[6])
|
||||
go send(ca[7])
|
||||
|
||||
changeNproc(4)
|
||||
go recv(ca[8])
|
||||
go recv(ca[9])
|
||||
go recv(ca[10])
|
||||
go recv(ca[11])
|
||||
|
||||
changeNproc(2)
|
||||
go sel(ca[4], ca[5], ca[6], ca[7], ca[0], ca[1], ca[2], ca[3])
|
||||
go sel(ca[0], ca[1], ca[2], ca[3], ca[8], ca[9], ca[10], ca[11])
|
||||
}
|
||||
|
||||
// wait for outstanding tests to finish
|
||||
func wait() {
|
||||
runtime.Gosched()
|
||||
for changeNproc(0) != 0 {
|
||||
runtime.Gosched()
|
||||
}
|
||||
}
|
||||
|
||||
// run all tests with specified buffer size
|
||||
func tests(c int) {
|
||||
ca := mkchan(c, 4)
|
||||
test1(ca[0])
|
||||
test1(ca[1])
|
||||
test1(ca[2])
|
||||
test1(ca[3])
|
||||
wait()
|
||||
|
||||
test2(c)
|
||||
wait()
|
||||
|
||||
test3(c)
|
||||
wait()
|
||||
|
||||
test4(c)
|
||||
wait()
|
||||
|
||||
test5(c)
|
||||
wait()
|
||||
|
||||
test6(c)
|
||||
wait()
|
||||
}
|
||||
|
||||
// run all test with 4 buffser sizes
|
||||
func main() {
|
||||
|
||||
tests(0)
|
||||
tests(1)
|
||||
tests(10)
|
||||
tests(100)
|
||||
|
||||
t := 4 * // buffer sizes
|
||||
(4*4 + // tests 1,2,3,4 channels
|
||||
8 + // test 5 channels
|
||||
12) * // test 6 channels
|
||||
76 // sends/recvs on a channel
|
||||
|
||||
if tots != t || totr != t {
|
||||
print("tots=", tots, " totr=", totr, " sb=", t, "\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
os.Exit(0)
|
||||
}
|
||||
Reference in New Issue
Block a user