github.com/llvm-mirror/llgo@v0.0.0-20190322182713-bf6f0a60fce1/third_party/gofrontend/libgo/go/runtime/malloc_test.go (about) 1 // 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 5 package runtime_test 6 7 import ( 8 "flag" 9 . "runtime" 10 "testing" 11 "time" 12 "unsafe" 13 ) 14 15 func TestMemStats(t *testing.T) { 16 t.Skip("skipping test with gccgo") 17 // Test that MemStats has sane values. 18 st := new(MemStats) 19 ReadMemStats(st) 20 21 // Everything except HeapReleased and HeapIdle, because they indeed can be 0. 22 if st.Alloc == 0 || st.TotalAlloc == 0 || st.Sys == 0 || st.Lookups == 0 || 23 st.Mallocs == 0 || st.Frees == 0 || st.HeapAlloc == 0 || st.HeapSys == 0 || 24 st.HeapInuse == 0 || st.HeapObjects == 0 || st.StackInuse == 0 || 25 st.StackSys == 0 || st.MSpanInuse == 0 || st.MSpanSys == 0 || st.MCacheInuse == 0 || 26 st.MCacheSys == 0 || st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 || 27 st.NextGC == 0 || st.NumGC == 0 { 28 t.Fatalf("Zero value: %+v", *st) 29 } 30 31 if st.Alloc > 1e10 || st.TotalAlloc > 1e11 || st.Sys > 1e10 || st.Lookups > 1e10 || 32 st.Mallocs > 1e10 || st.Frees > 1e10 || st.HeapAlloc > 1e10 || st.HeapSys > 1e10 || 33 st.HeapIdle > 1e10 || st.HeapInuse > 1e10 || st.HeapObjects > 1e10 || st.StackInuse > 1e10 || 34 st.StackSys > 1e10 || st.MSpanInuse > 1e10 || st.MSpanSys > 1e10 || st.MCacheInuse > 1e10 || 35 st.MCacheSys > 1e10 || st.BuckHashSys > 1e10 || st.GCSys > 1e10 || st.OtherSys > 1e10 || 36 st.NextGC > 1e10 || st.NumGC > 1e9 || st.PauseTotalNs > 1e11 { 37 t.Fatalf("Insanely high value (overflow?): %+v", *st) 38 } 39 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 if st.HeapIdle+st.HeapInuse != st.HeapSys { 45 t.Fatalf("HeapIdle(%d) + HeapInuse(%d) should be equal to HeapSys(%d), but isn't.", st.HeapIdle, st.HeapInuse, st.HeapSys) 46 } 47 48 if lpe := st.PauseEnd[int(st.NumGC+255)%len(st.PauseEnd)]; st.LastGC != lpe { 49 t.Fatalf("LastGC(%d) != last PauseEnd(%d)", st.LastGC, lpe) 50 } 51 52 var pauseTotal uint64 53 for _, pause := range st.PauseNs { 54 pauseTotal += pause 55 } 56 if int(st.NumGC) < len(st.PauseNs) { 57 // We have all pauses, so this should be exact. 58 if st.PauseTotalNs != pauseTotal { 59 t.Fatalf("PauseTotalNs(%d) != sum PauseNs(%d)", st.PauseTotalNs, pauseTotal) 60 } 61 } else { 62 if st.PauseTotalNs < pauseTotal { 63 t.Fatalf("PauseTotalNs(%d) < sum PauseNs(%d)", st.PauseTotalNs, pauseTotal) 64 } 65 } 66 } 67 68 func TestStringConcatenationAllocs(t *testing.T) { 69 t.Skip("skipping test with gccgo") 70 n := testing.AllocsPerRun(1e3, func() { 71 b := make([]byte, 10) 72 for i := 0; i < 10; i++ { 73 b[i] = byte(i) + '0' 74 } 75 s := "foo" + string(b) 76 if want := "foo0123456789"; s != want { 77 t.Fatalf("want %v, got %v", want, s) 78 } 79 }) 80 // Only string concatenation allocates. 81 if n != 1 { 82 t.Fatalf("want 1 allocation, got %v", n) 83 } 84 } 85 86 var mallocSink uintptr 87 88 func BenchmarkMalloc8(b *testing.B) { 89 var x uintptr 90 for i := 0; i < b.N; i++ { 91 p := new(int64) 92 x ^= uintptr(unsafe.Pointer(p)) 93 } 94 mallocSink = x 95 } 96 97 func BenchmarkMalloc16(b *testing.B) { 98 var x uintptr 99 for i := 0; i < b.N; i++ { 100 p := new([2]int64) 101 x ^= uintptr(unsafe.Pointer(p)) 102 } 103 mallocSink = x 104 } 105 106 func BenchmarkMallocTypeInfo8(b *testing.B) { 107 var x uintptr 108 for i := 0; i < b.N; i++ { 109 p := new(struct { 110 p [8 / unsafe.Sizeof(uintptr(0))]*int 111 }) 112 x ^= uintptr(unsafe.Pointer(p)) 113 } 114 mallocSink = x 115 } 116 117 func BenchmarkMallocTypeInfo16(b *testing.B) { 118 var x uintptr 119 for i := 0; i < b.N; i++ { 120 p := new(struct { 121 p [16 / unsafe.Sizeof(uintptr(0))]*int 122 }) 123 x ^= uintptr(unsafe.Pointer(p)) 124 } 125 mallocSink = x 126 } 127 128 var n = flag.Int("n", 1000, "number of goroutines") 129 130 func BenchmarkGoroutineSelect(b *testing.B) { 131 quit := make(chan struct{}) 132 read := func(ch chan struct{}) { 133 for { 134 select { 135 case _, ok := <-ch: 136 if !ok { 137 return 138 } 139 case <-quit: 140 return 141 } 142 } 143 } 144 benchHelper(b, *n, read) 145 } 146 147 func BenchmarkGoroutineBlocking(b *testing.B) { 148 read := func(ch chan struct{}) { 149 for { 150 if _, ok := <-ch; !ok { 151 return 152 } 153 } 154 } 155 benchHelper(b, *n, read) 156 } 157 158 func BenchmarkGoroutineForRange(b *testing.B) { 159 read := func(ch chan struct{}) { 160 for _ = range ch { 161 } 162 } 163 benchHelper(b, *n, read) 164 } 165 166 func benchHelper(b *testing.B, n int, read func(chan struct{})) { 167 m := make([]chan struct{}, n) 168 for i := range m { 169 m[i] = make(chan struct{}, 1) 170 go read(m[i]) 171 } 172 b.StopTimer() 173 b.ResetTimer() 174 GC() 175 176 for i := 0; i < b.N; i++ { 177 for _, ch := range m { 178 if ch != nil { 179 ch <- struct{}{} 180 } 181 } 182 time.Sleep(10 * time.Millisecond) 183 b.StartTimer() 184 GC() 185 b.StopTimer() 186 } 187 188 for _, ch := range m { 189 close(ch) 190 } 191 time.Sleep(10 * time.Millisecond) 192 } 193 194 func BenchmarkGoroutineIdle(b *testing.B) { 195 quit := make(chan struct{}) 196 fn := func() { 197 <-quit 198 } 199 for i := 0; i < *n; i++ { 200 go fn() 201 } 202 203 GC() 204 b.ResetTimer() 205 206 for i := 0; i < b.N; i++ { 207 GC() 208 } 209 210 b.StopTimer() 211 close(quit) 212 time.Sleep(10 * time.Millisecond) 213 }