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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [runtime/] [chan_test.go] - Rev 867

Go to most recent revision | Compare with Previous | Blame | View Log

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

import (
        "runtime"
        "sync"
        "sync/atomic"
        "testing"
)

func TestChanSendInterface(t *testing.T) {
        type mt struct{}
        m := &mt{}
        c := make(chan interface{}, 1)
        c <- m
        select {
        case c <- m:
        default:
        }
        select {
        case c <- m:
        case c <- &mt{}:
        default:
        }
}

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 TestMultiConsumer(t *testing.T) {
        const nwork = 23
        const niter = 271828

        pn := []int{2, 3, 7, 11, 13, 17, 19, 23, 27, 31}

        q := make(chan int, nwork*3)
        r := make(chan int, nwork*3)

        // workers
        var wg sync.WaitGroup
        for i := 0; i < nwork; i++ {
                wg.Add(1)
                go func(w int) {
                        for v := range q {
                                // mess with the fifo-ish nature of range
                                if pn[w%len(pn)] == v {
                                        runtime.Gosched()
                                }
                                r <- v
                        }
                        wg.Done()
                }(i)
        }

        // feeder & closer
        expect := 0
        go func() {
                for i := 0; i < niter; i++ {
                        v := pn[i%len(pn)]
                        expect += v
                        q <- v
                }
                close(q)  // no more work
                wg.Wait() // workers done
                close(r)  // ... so there can be no more results
        }()

        // consume & check
        n := 0
        s := 0
        for v := range r {
                n++
                s += v
        }
        if n != niter || s != expect {
                t.Errorf("Expected sum %d (got %d) from %d iter (saw %d)",
                        expect, s, niter, n)
        }
}

func BenchmarkSelectUncontended(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
        c := make(chan bool, procs)
        for p := 0; p < procs; p++ {
                go func() {
                        myc1 := make(chan int, 1)
                        myc2 := make(chan int, 1)
                        myc1 <- 0
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                                        select {
                                        case <-myc1:
                                                myc2 <- 0
                                        case <-myc2:
                                                myc1 <- 0
                                        }
                                }
                        }
                        c <- true
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
        }
}

func BenchmarkSelectContended(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
        c := make(chan bool, procs)
        myc1 := make(chan int, procs)
        myc2 := make(chan int, procs)
        for p := 0; p < procs; p++ {
                myc1 <- 0
                go func() {
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                                        select {
                                        case <-myc1:
                                                myc2 <- 0
                                        case <-myc2:
                                                myc1 <- 0
                                        }
                                }
                        }
                        c <- true
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
        }
}

func BenchmarkSelectNonblock(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
        c := make(chan bool, procs)
        for p := 0; p < procs; p++ {
                go func() {
                        myc1 := make(chan int)
                        myc2 := make(chan int)
                        myc3 := make(chan int, 1)
                        myc4 := make(chan int, 1)
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                                        select {
                                        case <-myc1:
                                        default:
                                        }
                                        select {
                                        case myc2 <- 0:
                                        default:
                                        }
                                        select {
                                        case <-myc3:
                                        default:
                                        }
                                        select {
                                        case myc4 <- 0:
                                        default:
                                        }
                                }
                        }
                        c <- true
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
        }
}

func BenchmarkChanUncontended(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
        c := make(chan bool, procs)
        for p := 0; p < procs; p++ {
                go func() {
                        myc := make(chan int, CallsPerSched)
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                                        myc <- 0
                                }
                                for g := 0; g < CallsPerSched; g++ {
                                        <-myc
                                }
                        }
                        c <- true
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
        }
}

func BenchmarkChanContended(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
        c := make(chan bool, procs)
        myc := make(chan int, procs*CallsPerSched)
        for p := 0; p < procs; p++ {
                go func() {
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                                        myc <- 0
                                }
                                for g := 0; g < CallsPerSched; g++ {
                                        <-myc
                                }
                        }
                        c <- true
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
        }
}

func BenchmarkChanSync(b *testing.B) {
        const CallsPerSched = 1000
        procs := 2
        N := int32(b.N / CallsPerSched / procs * procs)
        c := make(chan bool, procs)
        myc := make(chan int)
        for p := 0; p < procs; p++ {
                go func() {
                        for {
                                i := atomic.AddInt32(&N, -1)
                                if i < 0 {
                                        break
                                }
                                for g := 0; g < CallsPerSched; g++ {
                                        if i%2 == 0 {
                                                <-myc
                                                myc <- 0
                                        } else {
                                                myc <- 0
                                                <-myc
                                        }
                                }
                        }
                        c <- true
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
        }
}

func benchmarkChanProdCons(b *testing.B, chanSize, localWork int) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
        c := make(chan bool, 2*procs)
        myc := make(chan int, chanSize)
        for p := 0; p < procs; p++ {
                go func() {
                        foo := 0
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                                        for i := 0; i < localWork; i++ {
                                                foo *= 2
                                                foo /= 2
                                        }
                                        myc <- 1
                                }
                        }
                        myc <- 0
                        c <- foo == 42
                }()
                go func() {
                        foo := 0
                        for {
                                v := <-myc
                                if v == 0 {
                                        break
                                }
                                for i := 0; i < localWork; i++ {
                                        foo *= 2
                                        foo /= 2
                                }
                        }
                        c <- foo == 42
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
                <-c
        }
}

func BenchmarkChanProdCons0(b *testing.B) {
        benchmarkChanProdCons(b, 0, 0)
}

func BenchmarkChanProdCons10(b *testing.B) {
        benchmarkChanProdCons(b, 10, 0)
}

func BenchmarkChanProdCons100(b *testing.B) {
        benchmarkChanProdCons(b, 100, 0)
}

func BenchmarkChanProdConsWork0(b *testing.B) {
        benchmarkChanProdCons(b, 0, 100)
}

func BenchmarkChanProdConsWork10(b *testing.B) {
        benchmarkChanProdCons(b, 10, 100)
}

func BenchmarkChanProdConsWork100(b *testing.B) {
        benchmarkChanProdCons(b, 100, 100)
}

func BenchmarkChanCreation(b *testing.B) {
        const CallsPerSched = 1000
        procs := runtime.GOMAXPROCS(-1)
        N := int32(b.N / CallsPerSched)
        c := make(chan bool, procs)
        for p := 0; p < procs; p++ {
                go func() {
                        for atomic.AddInt32(&N, -1) >= 0 {
                                for g := 0; g < CallsPerSched; g++ {
                                        myc := make(chan int, 1)
                                        myc <- 0
                                        <-myc
                                }
                        }
                        c <- true
                }()
        }
        for p := 0; p < procs; p++ {
                <-c
        }
}

func BenchmarkChanSem(b *testing.B) {
        type Empty struct{}
        c := make(chan Empty, 1)
        for i := 0; i < b.N; i++ {
                c <- Empty{}
                <-c
        }
}

Go to most recent revision | 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.