github.com/go-asm/go@v1.21.1-0.20240213172139-40c5ead50c48/trace/v2/testdata/testprog/stress.go (about) 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 many interesting cases (network, syscalls, a little GC, busy goroutines, 6 // blocked goroutines, LockOSThread, pipes, and GOMAXPROCS). 7 8 //go:build ignore 9 10 package main 11 12 import ( 13 "log" 14 "net" 15 "os" 16 "runtime" 17 "runtime/trace" 18 "sync" 19 "time" 20 ) 21 22 func main() { 23 var wg sync.WaitGroup 24 done := make(chan bool) 25 26 // Create a goroutine blocked before tracing. 27 wg.Add(1) 28 go func() { 29 <-done 30 wg.Done() 31 }() 32 33 // Create a goroutine blocked in syscall before tracing. 34 rp, wp, err := os.Pipe() 35 if err != nil { 36 log.Fatalf("failed to create pipe: %v", err) 37 } 38 defer func() { 39 rp.Close() 40 wp.Close() 41 }() 42 wg.Add(1) 43 go func() { 44 var tmp [1]byte 45 rp.Read(tmp[:]) 46 <-done 47 wg.Done() 48 }() 49 time.Sleep(time.Millisecond) // give the goroutine above time to block 50 51 if err := trace.Start(os.Stdout); err != nil { 52 log.Fatalf("failed to start tracing: %v", err) 53 } 54 defer trace.Stop() 55 56 procs := runtime.GOMAXPROCS(10) 57 time.Sleep(50 * time.Millisecond) // test proc stop/start events 58 59 go func() { 60 runtime.LockOSThread() 61 for { 62 select { 63 case <-done: 64 return 65 default: 66 runtime.Gosched() 67 } 68 } 69 }() 70 71 runtime.GC() 72 // Trigger GC from malloc. 73 n := 512 74 for i := 0; i < n; i++ { 75 _ = make([]byte, 1<<20) 76 } 77 78 // Create a bunch of busy goroutines to load all Ps. 79 for p := 0; p < 10; p++ { 80 wg.Add(1) 81 go func() { 82 // Do something useful. 83 tmp := make([]byte, 1<<16) 84 for i := range tmp { 85 tmp[i]++ 86 } 87 _ = tmp 88 <-done 89 wg.Done() 90 }() 91 } 92 93 // Block in syscall. 94 wg.Add(1) 95 go func() { 96 var tmp [1]byte 97 rp.Read(tmp[:]) 98 <-done 99 wg.Done() 100 }() 101 102 // Test timers. 103 timerDone := make(chan bool) 104 go func() { 105 time.Sleep(time.Millisecond) 106 timerDone <- true 107 }() 108 <-timerDone 109 110 // A bit of network. 111 ln, err := net.Listen("tcp", "127.0.0.1:0") 112 if err != nil { 113 log.Fatalf("listen failed: %v", err) 114 } 115 defer ln.Close() 116 go func() { 117 c, err := ln.Accept() 118 if err != nil { 119 return 120 } 121 time.Sleep(time.Millisecond) 122 var buf [1]byte 123 c.Write(buf[:]) 124 c.Close() 125 }() 126 c, err := net.Dial("tcp", ln.Addr().String()) 127 if err != nil { 128 log.Fatalf("dial failed: %v", err) 129 } 130 var tmp [1]byte 131 c.Read(tmp[:]) 132 c.Close() 133 134 go func() { 135 runtime.Gosched() 136 select {} 137 }() 138 139 // Unblock helper goroutines and wait them to finish. 140 wp.Write(tmp[:]) 141 wp.Write(tmp[:]) 142 close(done) 143 wg.Wait() 144 145 runtime.GOMAXPROCS(procs) 146 }