1// run
2
3// Copyright 2010 The Go Authors.  All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test that selects do not consume undue memory.
8
9package main
10
11import "runtime"
12
13func sender(c chan int, n int) {
14	for i := 0; i < n; i++ {
15		c <- 1
16	}
17}
18
19func receiver(c, dummy chan int, n int) {
20	for i := 0; i < n; i++ {
21		select {
22		case <-c:
23			// nothing
24		case <-dummy:
25			panic("dummy")
26		}
27	}
28}
29
30func main() {
31	runtime.MemProfileRate = 0
32
33	c := make(chan int)
34	dummy := make(chan int)
35
36	// warm up
37	go sender(c, 100000)
38	receiver(c, dummy, 100000)
39	runtime.GC()
40	memstats := new(runtime.MemStats)
41	runtime.ReadMemStats(memstats)
42	alloc := memstats.Alloc
43
44	// second time shouldn't increase footprint by much
45	go sender(c, 100000)
46	receiver(c, dummy, 100000)
47	runtime.GC()
48	runtime.ReadMemStats(memstats)
49
50	// Be careful to avoid wraparound.
51	if memstats.Alloc > alloc && memstats.Alloc-alloc > 1.1e5 {
52		println("BUG: too much memory for 100,000 selects:", memstats.Alloc-alloc)
53	}
54}
55