summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/malloc_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/malloc_test.go')
-rw-r--r--src/pkg/runtime/malloc_test.go156
1 files changed, 156 insertions, 0 deletions
diff --git a/src/pkg/runtime/malloc_test.go b/src/pkg/runtime/malloc_test.go
new file mode 100644
index 000000000..128ec098c
--- /dev/null
+++ b/src/pkg/runtime/malloc_test.go
@@ -0,0 +1,156 @@
+// Copyright 2013 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 (
+ "flag"
+ . "runtime"
+ "testing"
+ "time"
+ "unsafe"
+)
+
+func TestMemStats(t *testing.T) {
+ // Test that MemStats has sane values.
+ st := new(MemStats)
+ ReadMemStats(st)
+ if st.HeapSys == 0 || st.StackSys == 0 || st.MSpanSys == 0 || st.MCacheSys == 0 ||
+ st.BuckHashSys == 0 || st.GCSys == 0 || st.OtherSys == 0 {
+ t.Fatalf("Zero sys value: %+v", *st)
+ }
+ if st.Sys != st.HeapSys+st.StackSys+st.MSpanSys+st.MCacheSys+
+ st.BuckHashSys+st.GCSys+st.OtherSys {
+ t.Fatalf("Bad sys value: %+v", *st)
+ }
+}
+
+var mallocSink uintptr
+
+func BenchmarkMalloc8(b *testing.B) {
+ var x uintptr
+ for i := 0; i < b.N; i++ {
+ p := new(int64)
+ x ^= uintptr(unsafe.Pointer(p))
+ }
+ mallocSink = x
+}
+
+func BenchmarkMalloc16(b *testing.B) {
+ var x uintptr
+ for i := 0; i < b.N; i++ {
+ p := new([2]int64)
+ x ^= uintptr(unsafe.Pointer(p))
+ }
+ mallocSink = x
+}
+
+func BenchmarkMallocTypeInfo8(b *testing.B) {
+ var x uintptr
+ for i := 0; i < b.N; i++ {
+ p := new(struct {
+ p [8 / unsafe.Sizeof(uintptr(0))]*int
+ })
+ x ^= uintptr(unsafe.Pointer(p))
+ }
+ mallocSink = x
+}
+
+func BenchmarkMallocTypeInfo16(b *testing.B) {
+ var x uintptr
+ for i := 0; i < b.N; i++ {
+ p := new(struct {
+ p [16 / unsafe.Sizeof(uintptr(0))]*int
+ })
+ x ^= uintptr(unsafe.Pointer(p))
+ }
+ mallocSink = x
+}
+
+var n = flag.Int("n", 1000, "number of goroutines")
+
+func BenchmarkGoroutineSelect(b *testing.B) {
+ quit := make(chan struct{})
+ read := func(ch chan struct{}) {
+ for {
+ select {
+ case _, ok := <-ch:
+ if !ok {
+ return
+ }
+ case <-quit:
+ return
+ }
+ }
+ }
+ benchHelper(b, *n, read)
+}
+
+func BenchmarkGoroutineBlocking(b *testing.B) {
+ read := func(ch chan struct{}) {
+ for {
+ if _, ok := <-ch; !ok {
+ return
+ }
+ }
+ }
+ benchHelper(b, *n, read)
+}
+
+func BenchmarkGoroutineForRange(b *testing.B) {
+ read := func(ch chan struct{}) {
+ for _ = range ch {
+ }
+ }
+ benchHelper(b, *n, read)
+}
+
+func benchHelper(b *testing.B, n int, read func(chan struct{})) {
+ m := make([]chan struct{}, n)
+ for i := range m {
+ m[i] = make(chan struct{}, 1)
+ go read(m[i])
+ }
+ b.StopTimer()
+ b.ResetTimer()
+ GC()
+
+ for i := 0; i < b.N; i++ {
+ for _, ch := range m {
+ if ch != nil {
+ ch <- struct{}{}
+ }
+ }
+ time.Sleep(10 * time.Millisecond)
+ b.StartTimer()
+ GC()
+ b.StopTimer()
+ }
+
+ for _, ch := range m {
+ close(ch)
+ }
+ time.Sleep(10 * time.Millisecond)
+}
+
+func BenchmarkGoroutineIdle(b *testing.B) {
+ quit := make(chan struct{})
+ fn := func() {
+ <-quit
+ }
+ for i := 0; i < *n; i++ {
+ go fn()
+ }
+
+ GC()
+ b.ResetTimer()
+
+ for i := 0; i < b.N; i++ {
+ GC()
+ }
+
+ b.StopTimer()
+ close(quit)
+ time.Sleep(10 * time.Millisecond)
+}