// $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;
	}
	panic("got ", v, " expected ", v0+1, "\n");
}

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