diff options
author | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
---|---|---|
committer | Tianon Gravi <admwiggin@gmail.com> | 2015-01-15 11:54:00 -0700 |
commit | f154da9e12608589e8d5f0508f908a0c3e88a1bb (patch) | |
tree | f8255d51e10c6f1e0ed69702200b966c9556a431 /src/pkg/runtime/stack_test.go | |
parent | 8d8329ed5dfb9622c82a9fbec6fd99a580f9c9f6 (diff) | |
download | golang-upstream/1.4.tar.gz |
Imported Upstream version 1.4upstream/1.4
Diffstat (limited to 'src/pkg/runtime/stack_test.go')
-rw-r--r-- | src/pkg/runtime/stack_test.go | 283 |
1 files changed, 0 insertions, 283 deletions
diff --git a/src/pkg/runtime/stack_test.go b/src/pkg/runtime/stack_test.go deleted file mode 100644 index f0c599ac5..000000000 --- a/src/pkg/runtime/stack_test.go +++ /dev/null @@ -1,283 +0,0 @@ -// Copyright 2012 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 ( - . "runtime" - "sync" - "testing" - "time" - "unsafe" -) - -// See stack.h. -const ( - StackGuard = 256 - StackLimit = 128 -) - -// 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 -// doing the actual checking and reporting from the suspect functions, -// we minimize the possibility of crashes during the test itself. -// -// Exhaustive test for http://golang.org/issue/3310. -// The linker used to get a few sizes near the segment size wrong: -// -// --- FAIL: TestStackSplit (0.01 seconds) -// stack_test.go:22: after runtime_test.stack3812: sp=0x7f7818d5d078 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3816: sp=0x7f7818d5d078 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3820: sp=0x7f7818d5d070 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3824: sp=0x7f7818d5d070 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3828: sp=0x7f7818d5d068 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3832: sp=0x7f7818d5d068 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3836: sp=0x7f7818d5d060 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3840: sp=0x7f7818d5d060 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3844: sp=0x7f7818d5d058 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3848: sp=0x7f7818d5d058 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3852: sp=0x7f7818d5d050 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3856: sp=0x7f7818d5d050 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3860: sp=0x7f7818d5d048 < limit=0x7f7818d5d080 -// stack_test.go:22: after runtime_test.stack3864: sp=0x7f7818d5d048 < limit=0x7f7818d5d080 -// FAIL -func TestStackSplit(t *testing.T) { - for _, f := range splitTests { - sp, guard := f() - bottom := guard - StackGuard - if sp < bottom+StackLimit { - fun := FuncForPC(**(**uintptr)(unsafe.Pointer(&f))) - t.Errorf("after %s: sp=%#x < limit=%#x (guard=%#x, bottom=%#x)", - fun.Name(), sp, bottom+StackLimit, guard, bottom) - } - } -} - -var Used byte - -func use(buf []byte) { - for _, c := range buf { - Used += c - } -} - -// 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 = 256 - 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 - } - - // The goroutines have signaled via c that they are ready to exit. - // Give them a chance to exit by sleeping. If we don't wait, we - // might not reuse them on the next batch. - time.Sleep(10 * time.Millisecond) - } - 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) - } - // Due to broken stack memory accounting (http://golang.org/issue/7468), - // StackInuse can decrease during function execution, so we cast the values to int64. - inuse := int64(s1.StackInuse) - int64(s0.StackInuse) - t.Logf("Inuse %vMB for stack mem", inuse>>20) - if inuse > 4<<20 { - t.Fatalf("Stack inuse: want %v, got %v", 4<<20, inuse) - } -} - -// Test stack growing in different contexts. -func TestStackGrowth(t *testing.T) { - switch GOARCH { - case "386", "arm": - t.Skipf("skipping test on %q; see issue 8083", GOARCH) - } - t.Parallel() - var wg sync.WaitGroup - - // in a normal goroutine - wg.Add(1) - go func() { - defer wg.Done() - growStack() - }() - wg.Wait() - - // in locked goroutine - wg.Add(1) - go func() { - defer wg.Done() - LockOSThread() - growStack() - UnlockOSThread() - }() - wg.Wait() - - // in finalizer - wg.Add(1) - go func() { - defer wg.Done() - done := make(chan bool) - go func() { - s := new(string) - SetFinalizer(s, func(ss *string) { - growStack() - done <- true - }) - s = nil - done <- true - }() - <-done - GC() - select { - case <-done: - case <-time.After(20 * time.Second): - t.Fatal("finalizer did not run") - } - }() - wg.Wait() -} - -// ... and in init -//func init() { -// growStack() -//} - -func growStack() { - n := 1 << 10 - if testing.Short() { - n = 1 << 8 - } - for i := 0; i < n; i++ { - x := 0 - growStackIter(&x, i) - if x != i+1 { - panic("stack is corrupted") - } - } - GC() -} - -// This function is not an anonimous func, so that the compiler can do escape -// analysis and place x on stack (and subsequently stack growth update the pointer). -func growStackIter(p *int, n int) { - if n == 0 { - *p = n + 1 - GC() - return - } - *p = n + 1 - x := 0 - growStackIter(&x, n-1) - if x != n { - panic("stack is corrupted") - } -} - -func TestStackGrowthCallback(t *testing.T) { - t.Parallel() - var wg sync.WaitGroup - - // test stack growth at chan op - wg.Add(1) - go func() { - defer wg.Done() - c := make(chan int, 1) - growStackWithCallback(func() { - c <- 1 - <-c - }) - }() - - // test stack growth at map op - wg.Add(1) - go func() { - defer wg.Done() - m := make(map[int]int) - growStackWithCallback(func() { - _, _ = m[1] - m[1] = 1 - }) - }() - - // test stack growth at goroutine creation - wg.Add(1) - go func() { - defer wg.Done() - growStackWithCallback(func() { - done := make(chan bool) - go func() { - done <- true - }() - <-done - }) - }() - - wg.Wait() -} - -func growStackWithCallback(cb func()) { - var f func(n int) - f = func(n int) { - if n == 0 { - cb() - return - } - f(n - 1) - } - for i := 0; i < 1<<10; i++ { - f(i) - } -} - -// TestDeferPtrs tests the adjustment of Defer's argument pointers (p aka &y) -// during a stack copy. -func set(p *int, x int) { - *p = x -} -func TestDeferPtrs(t *testing.T) { - var y int - - defer func() { - if y != 42 { - t.Errorf("defer's stack references were not adjusted appropriately") - } - }() - defer set(&y, 42) - growStack() -} |