1// run
2
3// Copyright 2015 The Go Authors. All rights reserved.
4// Use of this source code is governed by a BSD-style
5// license that can be found in the LICENSE file.
6
7// Test that stack barriers are reset when a goroutine exits without
8// returning.
9
10package main
11
12import (
13	"runtime"
14	"sync/atomic"
15	"time"
16)
17
18func main() {
19	// Let the garbage collector run concurrently.
20	runtime.GOMAXPROCS(2)
21
22	var x [100][]byte
23
24	for i := range x {
25		var done int32
26
27		go func() {
28			// Use enough stack to get stack barriers, but
29			// not so much that we go over _FixedStack.
30			// There's a very narrow window here on most
31			// OSs, so we basically can't do anything (not
32			// even a time.Sleep or a channel).
33			var buf [1024]byte
34			buf[0]++
35			for atomic.LoadInt32(&done) == 0 {
36				runtime.Gosched()
37			}
38			atomic.StoreInt32(&done, 0)
39			// Exit without unwinding stack barriers.
40			runtime.Goexit()
41		}()
42
43		// Generate some garbage.
44		x[i] = make([]byte, 1024*1024)
45
46		// Give GC some time to install stack barriers in the G.
47		time.Sleep(50 * time.Microsecond)
48		atomic.StoreInt32(&done, 1)
49		for atomic.LoadInt32(&done) == 1 {
50			runtime.Gosched()
51		}
52	}
53}
54