// $G $D/$F.go && $L $F.$A && ./$A.out

// 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.

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)
}
