Source file src/internal/trace/testdata/testprog/stress-start-stop.go

     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  	"bytes"
    14  	"io"
    15  	"log"
    16  	"net"
    17  	"os"
    18  	"runtime"
    19  	"runtime/trace"
    20  	"sync"
    21  	"time"
    22  )
    23  
    24  func main() {
    25  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(8))
    26  	outerDone := make(chan bool)
    27  
    28  	go func() {
    29  		defer func() {
    30  			outerDone <- true
    31  		}()
    32  
    33  		var wg sync.WaitGroup
    34  		done := make(chan bool)
    35  
    36  		wg.Add(1)
    37  		go func() {
    38  			<-done
    39  			wg.Done()
    40  		}()
    41  
    42  		rp, wp, err := os.Pipe()
    43  		if err != nil {
    44  			log.Fatalf("failed to create pipe: %v", err)
    45  			return
    46  		}
    47  		defer func() {
    48  			rp.Close()
    49  			wp.Close()
    50  		}()
    51  		wg.Add(1)
    52  		go func() {
    53  			var tmp [1]byte
    54  			rp.Read(tmp[:])
    55  			<-done
    56  			wg.Done()
    57  		}()
    58  		time.Sleep(time.Millisecond)
    59  
    60  		go func() {
    61  			runtime.LockOSThread()
    62  			for {
    63  				select {
    64  				case <-done:
    65  					return
    66  				default:
    67  					runtime.Gosched()
    68  				}
    69  			}
    70  		}()
    71  
    72  		runtime.GC()
    73  		// Trigger GC from malloc.
    74  		n := 512
    75  		for i := 0; i < n; i++ {
    76  			_ = make([]byte, 1<<20)
    77  		}
    78  
    79  		// Create a bunch of busy goroutines to load all Ps.
    80  		for p := 0; p < 10; p++ {
    81  			wg.Add(1)
    82  			go func() {
    83  				// Do something useful.
    84  				tmp := make([]byte, 1<<16)
    85  				for i := range tmp {
    86  					tmp[i]++
    87  				}
    88  				_ = tmp
    89  				<-done
    90  				wg.Done()
    91  			}()
    92  		}
    93  
    94  		// Block in syscall.
    95  		wg.Add(1)
    96  		go func() {
    97  			var tmp [1]byte
    98  			rp.Read(tmp[:])
    99  			<-done
   100  			wg.Done()
   101  		}()
   102  
   103  		runtime.GOMAXPROCS(runtime.GOMAXPROCS(1))
   104  
   105  		// Test timers.
   106  		timerDone := make(chan bool)
   107  		go func() {
   108  			time.Sleep(time.Millisecond)
   109  			timerDone <- true
   110  		}()
   111  		<-timerDone
   112  
   113  		// A bit of network.
   114  		ln, err := net.Listen("tcp", "127.0.0.1:0")
   115  		if err != nil {
   116  			log.Fatalf("listen failed: %v", err)
   117  			return
   118  		}
   119  		defer ln.Close()
   120  		go func() {
   121  			c, err := ln.Accept()
   122  			if err != nil {
   123  				return
   124  			}
   125  			time.Sleep(time.Millisecond)
   126  			var buf [1]byte
   127  			c.Write(buf[:])
   128  			c.Close()
   129  		}()
   130  		c, err := net.Dial("tcp", ln.Addr().String())
   131  		if err != nil {
   132  			log.Fatalf("dial failed: %v", err)
   133  			return
   134  		}
   135  		var tmp [1]byte
   136  		c.Read(tmp[:])
   137  		c.Close()
   138  
   139  		go func() {
   140  			runtime.Gosched()
   141  			select {}
   142  		}()
   143  
   144  		// Unblock helper goroutines and wait them to finish.
   145  		wp.Write(tmp[:])
   146  		wp.Write(tmp[:])
   147  		close(done)
   148  		wg.Wait()
   149  	}()
   150  
   151  	const iters = 5
   152  	for i := 0; i < iters; i++ {
   153  		var w io.Writer
   154  		if i == iters-1 {
   155  			w = os.Stdout
   156  		} else {
   157  			w = new(bytes.Buffer)
   158  		}
   159  		if err := trace.Start(w); err != nil {
   160  			log.Fatalf("failed to start tracing: %v", err)
   161  		}
   162  		time.Sleep(time.Millisecond)
   163  		trace.Stop()
   164  	}
   165  	<-outerDone
   166  }
   167  

View as plain text