summaryrefslogtreecommitdiff
path: root/src/pkg/runtime/stack_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/runtime/stack_test.go')
-rw-r--r--src/pkg/runtime/stack_test.go51
1 files changed, 50 insertions, 1 deletions
diff --git a/src/pkg/runtime/stack_test.go b/src/pkg/runtime/stack_test.go
index 01c6b6e2f..759f7c46e 100644
--- a/src/pkg/runtime/stack_test.go
+++ b/src/pkg/runtime/stack_test.go
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// Test stack split logic by calling functions of every frame size
+// Test stack split logic by calling functions of every frame size
// from near 0 up to and beyond the default segment size (4k).
// Each of those functions reports its SP + stack limit, and then
// the test (the caller) checks that those make sense. By not
@@ -34,6 +34,7 @@ package runtime_test
import (
. "runtime"
"testing"
+ "time"
"unsafe"
)
@@ -1526,3 +1527,51 @@ func stack4988() (uintptr, uintptr) { var buf [4988]byte; use(buf[:]); return St
func stack4992() (uintptr, uintptr) { var buf [4992]byte; use(buf[:]); return Stackguard() }
func stack4996() (uintptr, uintptr) { var buf [4996]byte; use(buf[:]); return Stackguard() }
func stack5000() (uintptr, uintptr) { var buf [5000]byte; use(buf[:]); return Stackguard() }
+
+// TestStackMem measures per-thread stack segment cache behavior.
+// The test consumed up to 500MB in the past.
+func TestStackMem(t *testing.T) {
+ const (
+ BatchSize = 32
+ BatchCount = 512
+ ArraySize = 1024
+ RecursionDepth = 128
+ )
+ if testing.Short() {
+ return
+ }
+ defer GOMAXPROCS(GOMAXPROCS(BatchSize))
+ s0 := new(MemStats)
+ ReadMemStats(s0)
+ for b := 0; b < BatchCount; b++ {
+ c := make(chan bool, BatchSize)
+ for i := 0; i < BatchSize; i++ {
+ go func() {
+ var f func(k int, a [ArraySize]byte)
+ f = func(k int, a [ArraySize]byte) {
+ if k == 0 {
+ time.Sleep(time.Millisecond)
+ return
+ }
+ f(k-1, a)
+ }
+ f(RecursionDepth, [ArraySize]byte{})
+ c <- true
+ }()
+ }
+ for i := 0; i < BatchSize; i++ {
+ <-c
+ }
+ }
+ s1 := new(MemStats)
+ ReadMemStats(s1)
+ consumed := s1.StackSys - s0.StackSys
+ t.Logf("Consumed %vMB for stack mem", consumed>>20)
+ estimate := uint64(8 * BatchSize * ArraySize * RecursionDepth) // 8 is to reduce flakiness.
+ if consumed > estimate {
+ t.Fatalf("Stack mem: want %v, got %v", estimate, consumed)
+ }
+ if s1.StackInuse > 4<<20 {
+ t.Fatalf("Stack inuse: want %v, got %v", 4<<20, s1.StackInuse)
+ }
+}