diff --git a/src/pkg/runtime/malloc_test.go b/src/pkg/runtime/malloc_test.go index 2b686a6e7e..128ec098cb 100644 --- a/src/pkg/runtime/malloc_test.go +++ b/src/pkg/runtime/malloc_test.go @@ -5,8 +5,10 @@ package runtime_test import ( + "flag" . "runtime" "testing" + "time" "unsafe" ) @@ -65,3 +67,90 @@ func BenchmarkMallocTypeInfo16(b *testing.B) { } 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) +} diff --git a/src/pkg/runtime/mgc0.c b/src/pkg/runtime/mgc0.c index fe9c18177c..7ebc2912ea 100644 --- a/src/pkg/runtime/mgc0.c +++ b/src/pkg/runtime/mgc0.c @@ -19,7 +19,7 @@ enum { Debug = 0, DebugMark = 0, // run second pass to check mark CollectStats = 0, - ScanStackByFrames = 1, + ScanStackByFrames = 0, IgnorePreciseGC = 0, // Four bits per word (see #defines below). @@ -1474,6 +1474,7 @@ addstackroots(G *gp) USED(guard); runtime·gentraceback(pc, sp, lr, gp, 0, nil, 0x7fffffff, addframeroots, nil, false); } else { + USED(lr); USED(pc); n = 0; while(stk) {