1// Copyright 2023 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// Tests a GC-heavy program. This is useful for shaking out
6// all sorts of corner cases about GC-related ranges.
7
8//go:build ignore
9
10package main
11
12import (
13	"log"
14	"os"
15	"runtime"
16	"runtime/trace"
17	"time"
18)
19
20type node struct {
21	children [4]*node
22	data     [128]byte
23}
24
25func makeTree(depth int) *node {
26	if depth == 0 {
27		return new(node)
28	}
29	return &node{
30		children: [4]*node{
31			makeTree(depth - 1),
32			makeTree(depth - 1),
33			makeTree(depth - 1),
34			makeTree(depth - 1),
35		},
36	}
37}
38
39var trees [16]*node
40var ballast *[16]*[1024]*node
41var sink [][]byte
42
43func main() {
44	for i := range trees {
45		trees[i] = makeTree(6)
46	}
47	ballast = new([16]*[1024]*node)
48	for i := range ballast {
49		ballast[i] = new([1024]*node)
50		for j := range ballast[i] {
51			ballast[i][j] = &node{
52				data: [128]byte{1, 2, 3, 4},
53			}
54		}
55	}
56
57	procs := runtime.GOMAXPROCS(-1)
58	sink = make([][]byte, procs)
59
60	for i := 0; i < procs; i++ {
61		i := i
62		go func() {
63			for {
64				sink[i] = make([]byte, 4<<10)
65			}
66		}()
67	}
68	// Increase the chance that we end up starting and stopping
69	// mid-GC by only starting to trace after a few milliseconds.
70	time.Sleep(5 * time.Millisecond)
71
72	// Start tracing.
73	if err := trace.Start(os.Stdout); err != nil {
74		log.Fatalf("failed to start tracing: %v", err)
75	}
76	defer trace.Stop()
77
78	// Let the tracing happen for a bit.
79	time.Sleep(400 * time.Millisecond)
80}
81