OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [testsuite/] [go.test/] [test/] [ken/] [chan.go] - Rev 700

Compare with Previous | Blame | View Log

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

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.