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.
15 func TestMemStats(t
*testing
.T
) {
16 t
.Skip("skipping test with gccgo")
18 // Make sure there's at least one forced GC.
21 // Test that MemStats has sane values.
25 // Everything except HeapReleased, HeapIdle, and NumGC,
26 // because they indeed can be 0.
27 if st
.Alloc
== 0 || st
.TotalAlloc
== 0 || st
.Sys
== 0 || st
.Lookups
== 0 ||
28 st
.Mallocs
== 0 || st
.Frees
== 0 || st
.HeapAlloc
== 0 || st
.HeapSys
== 0 ||
29 st
.HeapInuse
== 0 || st
.HeapObjects
== 0 || st
.StackInuse
== 0 ||
30 st
.StackSys
== 0 || st
.MSpanInuse
== 0 || st
.MSpanSys
== 0 || st
.MCacheInuse
== 0 ||
31 st
.MCacheSys
== 0 || st
.BuckHashSys
== 0 || st
.GCSys
== 0 || st
.OtherSys
== 0 ||
32 st
.NextGC
== 0 || st
.NumForcedGC
== 0 {
33 t
.Fatalf("Zero value: %+v", *st
)
36 if st
.Alloc
> 1e10 || st
.TotalAlloc
> 1e11 || st
.Sys
> 1e10 || st
.Lookups
> 1e10 ||
37 st
.Mallocs
> 1e10 || st
.Frees
> 1e10 || st
.HeapAlloc
> 1e10 || st
.HeapSys
> 1e10 ||
38 st
.HeapIdle
> 1e10 || st
.HeapInuse
> 1e10 || st
.HeapObjects
> 1e10 || st
.StackInuse
> 1e10 ||
39 st
.StackSys
> 1e10 || st
.MSpanInuse
> 1e10 || st
.MSpanSys
> 1e10 || st
.MCacheInuse
> 1e10 ||
40 st
.MCacheSys
> 1e10 || st
.BuckHashSys
> 1e10 || st
.GCSys
> 1e10 || st
.OtherSys
> 1e10 ||
41 st
.NextGC
> 1e10 || st
.NumGC
> 1e9 || st
.NumForcedGC
> 1e9 || st
.PauseTotalNs
> 1e11
{
42 t
.Fatalf("Insanely high value (overflow?): %+v", *st
)
44 if st
.Sys
!= st
.HeapSys
+st
.StackSys
+st
.MSpanSys
+st
.MCacheSys
+
45 st
.BuckHashSys
+st
.GCSys
+st
.OtherSys
{
46 t
.Fatalf("Bad sys value: %+v", *st
)
49 if st
.HeapIdle
+st
.HeapInuse
!= st
.HeapSys
{
50 t
.Fatalf("HeapIdle(%d) + HeapInuse(%d) should be equal to HeapSys(%d), but isn't.", st
.HeapIdle
, st
.HeapInuse
, st
.HeapSys
)
53 if lpe
:= st
.PauseEnd
[int(st
.NumGC
+255)%len
(st
.PauseEnd
)]; st
.LastGC
!= lpe
{
54 t
.Fatalf("LastGC(%d) != last PauseEnd(%d)", st
.LastGC
, lpe
)
58 for _
, pause
:= range st
.PauseNs
{
61 if int(st
.NumGC
) < len(st
.PauseNs
) {
62 // We have all pauses, so this should be exact.
63 if st
.PauseTotalNs
!= pauseTotal
{
64 t
.Fatalf("PauseTotalNs(%d) != sum PauseNs(%d)", st
.PauseTotalNs
, pauseTotal
)
66 for i
:= int(st
.NumGC
); i
< len(st
.PauseNs
); i
++ {
67 if st
.PauseNs
[i
] != 0 {
68 t
.Fatalf("Non-zero PauseNs[%d]: %+v", i
, st
)
70 if st
.PauseEnd
[i
] != 0 {
71 t
.Fatalf("Non-zero PauseEnd[%d]: %+v", i
, st
)
75 if st
.PauseTotalNs
< pauseTotal
{
76 t
.Fatalf("PauseTotalNs(%d) < sum PauseNs(%d)", st
.PauseTotalNs
, pauseTotal
)
80 if st
.NumForcedGC
> st
.NumGC
{
81 t
.Fatalf("NumForcedGC(%d) > NumGC(%d)", st
.NumForcedGC
, st
.NumGC
)
85 func TestStringConcatenationAllocs(t
*testing
.T
) {
86 t
.Skip("skipping test with gccgo")
87 n
:= testing
.AllocsPerRun(1e3
, func() {
89 for i
:= 0; i
< 10; i
++ {
92 s
:= "foo" + string(b
)
93 if want
:= "foo0123456789"; s
!= want
{
94 t
.Fatalf("want %v, got %v", want
, s
)
97 // Only string concatenation allocates.
99 t
.Fatalf("want 1 allocation, got %v", n
)
103 func TestTinyAlloc(t
*testing
.T
) {
105 var v
[N
]unsafe
.Pointer
107 v
[i
] = unsafe
.Pointer(new(byte))
110 chunks
:= make(map[uintptr]bool, N
)
111 for _
, p
:= range v
{
112 chunks
[uintptr(p
)&^7] = true
115 if len(chunks
) == N
{
116 t
.Fatal("no bytes allocated within the same 8-byte chunk")
120 var mallocSink
uintptr
122 func BenchmarkMalloc8(b
*testing
.B
) {
124 for i
:= 0; i
< b
.N
; i
++ {
126 x
^= uintptr(unsafe
.Pointer(p
))
131 func BenchmarkMalloc16(b
*testing
.B
) {
133 for i
:= 0; i
< b
.N
; i
++ {
135 x
^= uintptr(unsafe
.Pointer(p
))
140 func BenchmarkMallocTypeInfo8(b
*testing
.B
) {
142 for i
:= 0; i
< b
.N
; i
++ {
144 p
[8 / unsafe
.Sizeof(uintptr(0))]*int
146 x
^= uintptr(unsafe
.Pointer(p
))
151 func BenchmarkMallocTypeInfo16(b
*testing
.B
) {
153 for i
:= 0; i
< b
.N
; i
++ {
155 p
[16 / unsafe
.Sizeof(uintptr(0))]*int
157 x
^= uintptr(unsafe
.Pointer(p
))
162 var n
= flag
.Int("n", 1000, "number of goroutines")
164 func BenchmarkGoroutineSelect(b
*testing
.B
) {
165 quit
:= make(chan struct{})
166 read
:= func(ch
chan struct{}) {
178 benchHelper(b
, *n
, read
)
181 func BenchmarkGoroutineBlocking(b
*testing
.B
) {
182 read
:= func(ch
chan struct{}) {
184 if _
, ok
:= <-ch
; !ok
{
189 benchHelper(b
, *n
, read
)
192 func BenchmarkGoroutineForRange(b
*testing
.B
) {
193 read
:= func(ch
chan struct{}) {
197 benchHelper(b
, *n
, read
)
200 func benchHelper(b
*testing
.B
, n
int, read
func(chan struct{})) {
201 m
:= make([]chan struct{}, n
)
203 m
[i
] = make(chan struct{}, 1)
210 for i
:= 0; i
< b
.N
; i
++ {
211 for _
, ch
:= range m
{
216 time
.Sleep(10 * time
.Millisecond
)
222 for _
, ch
:= range m
{
225 time
.Sleep(10 * time
.Millisecond
)
228 func BenchmarkGoroutineIdle(b
*testing
.B
) {
229 quit
:= make(chan struct{})
233 for i
:= 0; i
< *n
; i
++ {
240 for i
:= 0; i
< b
.N
; i
++ {
246 time
.Sleep(10 * time
.Millisecond
)