blob: 211d78dc8a95f35473188997886adb1ee529cc7d [file] [log] [blame]
Dmitriy Vyukov915784e2013-05-15 21:22:32 +04001// Copyright 2013 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5package runtime_test
6
7import (
Russ Coxc3dadca2013-10-02 11:59:53 -04008 "flag"
Dmitriy Vyukova33ef8d2013-09-06 16:55:40 -04009 . "runtime"
Dmitriy Vyukov915784e2013-05-15 21:22:32 +040010 "testing"
Russ Coxc3dadca2013-10-02 11:59:53 -040011 "time"
Dmitriy Vyukov915784e2013-05-15 21:22:32 +040012 "unsafe"
13)
14
Dmitriy Vyukova33ef8d2013-09-06 16:55:40 -040015func TestMemStats(t *testing.T) {
16 // Test that MemStats has sane values.
17 st := new(MemStats)
18 ReadMemStats(st)
Dmitriy Vyukov30ef2c72014-08-19 11:46:05 +040019
20 // Everything except HeapReleased, because it indeed can be 0.
21 if st.Alloc == 0 || st.TotalAlloc == 0 || st.Sys == 0 || st.Lookups == 0 ||
22 st.Mallocs == 0 || st.Frees == 0 || st.HeapAlloc == 0 || st.HeapSys == 0 ||
23 st.HeapIdle == 0 || st.HeapInuse == 0 || st.HeapObjects == 0 || st.StackInuse == 0 ||
24 st.StackSys == 0 || st.MSpanInuse == 0 || st.MSpanSys == 0 || st.MCacheInuse == 0 ||
25 st.MCacheSys == 0 || st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 ||
26 st.NextGC == 0 || st.NumGC == 0 {
27 t.Fatalf("Zero value: %+v", *st)
Dmitriy Vyukova33ef8d2013-09-06 16:55:40 -040028 }
Dmitriy Vyukov30ef2c72014-08-19 11:46:05 +040029
30 if st.Alloc > 1e10 || st.TotalAlloc > 1e11 || st.Sys > 1e10 || st.Lookups > 1e10 ||
31 st.Mallocs > 1e10 || st.Frees > 1e10 || st.HeapAlloc > 1e10 || st.HeapSys > 1e10 ||
32 st.HeapIdle > 1e10 || st.HeapInuse > 1e10 || st.HeapObjects > 1e10 || st.StackInuse > 1e10 ||
33 st.StackSys > 1e10 || st.MSpanInuse > 1e10 || st.MSpanSys > 1e10 || st.MCacheInuse > 1e10 ||
34 st.MCacheSys > 1e10 || st.BuckHashSys > 1e10 || st.GCSys > 1e10 || st.OtherSys > 1e10 ||
35 st.NextGC > 1e10 || st.NumGC > 1e9 {
36 t.Fatalf("Insanely high value (overflow?): %+v", *st)
37 }
38
Dmitriy Vyukova33ef8d2013-09-06 16:55:40 -040039 if st.Sys != st.HeapSys+st.StackSys+st.MSpanSys+st.MCacheSys+
40 st.BuckHashSys+st.GCSys+st.OtherSys {
41 t.Fatalf("Bad sys value: %+v", *st)
42 }
43}
44
Dmitriy Vyukov915784e2013-05-15 21:22:32 +040045var mallocSink uintptr
46
47func BenchmarkMalloc8(b *testing.B) {
48 var x uintptr
49 for i := 0; i < b.N; i++ {
50 p := new(int64)
51 x ^= uintptr(unsafe.Pointer(p))
52 }
53 mallocSink = x
54}
55
56func BenchmarkMalloc16(b *testing.B) {
57 var x uintptr
58 for i := 0; i < b.N; i++ {
59 p := new([2]int64)
60 x ^= uintptr(unsafe.Pointer(p))
61 }
62 mallocSink = x
63}
64
65func BenchmarkMallocTypeInfo8(b *testing.B) {
66 var x uintptr
67 for i := 0; i < b.N; i++ {
68 p := new(struct {
69 p [8 / unsafe.Sizeof(uintptr(0))]*int
70 })
71 x ^= uintptr(unsafe.Pointer(p))
72 }
73 mallocSink = x
74}
75
76func BenchmarkMallocTypeInfo16(b *testing.B) {
77 var x uintptr
78 for i := 0; i < b.N; i++ {
79 p := new(struct {
80 p [16 / unsafe.Sizeof(uintptr(0))]*int
81 })
82 x ^= uintptr(unsafe.Pointer(p))
83 }
84 mallocSink = x
85}
Russ Coxc3dadca2013-10-02 11:59:53 -040086
Dmitriy Vyukovcd17a712014-07-29 11:01:02 +040087type LargeStruct struct {
88 x [16][]byte
89}
90
91func BenchmarkMallocLargeStruct(b *testing.B) {
92 var x uintptr
93 for i := 0; i < b.N; i++ {
94 p := make([]LargeStruct, 2)
95 x ^= uintptr(unsafe.Pointer(&p[0]))
96 }
97 mallocSink = x
98}
99
Russ Coxc3dadca2013-10-02 11:59:53 -0400100var n = flag.Int("n", 1000, "number of goroutines")
101
102func BenchmarkGoroutineSelect(b *testing.B) {
103 quit := make(chan struct{})
104 read := func(ch chan struct{}) {
105 for {
106 select {
107 case _, ok := <-ch:
108 if !ok {
109 return
110 }
111 case <-quit:
112 return
113 }
114 }
115 }
116 benchHelper(b, *n, read)
117}
118
119func BenchmarkGoroutineBlocking(b *testing.B) {
120 read := func(ch chan struct{}) {
121 for {
122 if _, ok := <-ch; !ok {
123 return
124 }
125 }
126 }
127 benchHelper(b, *n, read)
128}
129
130func BenchmarkGoroutineForRange(b *testing.B) {
131 read := func(ch chan struct{}) {
Robert Griesemer8a23c002014-07-16 16:29:51 -0700132 for range ch {
Russ Coxc3dadca2013-10-02 11:59:53 -0400133 }
134 }
135 benchHelper(b, *n, read)
136}
137
138func benchHelper(b *testing.B, n int, read func(chan struct{})) {
139 m := make([]chan struct{}, n)
140 for i := range m {
141 m[i] = make(chan struct{}, 1)
142 go read(m[i])
143 }
144 b.StopTimer()
145 b.ResetTimer()
146 GC()
147
148 for i := 0; i < b.N; i++ {
149 for _, ch := range m {
150 if ch != nil {
151 ch <- struct{}{}
152 }
153 }
154 time.Sleep(10 * time.Millisecond)
155 b.StartTimer()
156 GC()
157 b.StopTimer()
158 }
159
160 for _, ch := range m {
161 close(ch)
162 }
163 time.Sleep(10 * time.Millisecond)
164}
165
166func BenchmarkGoroutineIdle(b *testing.B) {
167 quit := make(chan struct{})
168 fn := func() {
169 <-quit
170 }
171 for i := 0; i < *n; i++ {
172 go fn()
173 }
174
175 GC()
176 b.ResetTimer()
177
178 for i := 0; i < b.N; i++ {
179 GC()
180 }
181
182 b.StopTimer()
183 close(quit)
184 time.Sleep(10 * time.Millisecond)
185}