Source file src/internal/trace/testdata/testprog/futile-wakeup.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 to make sure the runtime doesn't generate futile wakeups. For example,
     6  // it makes sure that a block on a channel send that unblocks briefly only to
     7  // immediately go back to sleep (in such a way that doesn't reveal any useful
     8  // information, and is purely an artifact of the runtime implementation) doesn't
     9  // make it into the trace.
    10  
    11  //go:build ignore
    12  
    13  package main
    14  
    15  import (
    16  	"context"
    17  	"log"
    18  	"os"
    19  	"runtime"
    20  	"runtime/trace"
    21  	"sync"
    22  )
    23  
    24  func main() {
    25  	if err := trace.Start(os.Stdout); err != nil {
    26  		log.Fatalf("failed to start tracing: %v", err)
    27  	}
    28  
    29  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(8))
    30  	c0 := make(chan int, 1)
    31  	c1 := make(chan int, 1)
    32  	c2 := make(chan int, 1)
    33  	const procs = 2
    34  	var done sync.WaitGroup
    35  	done.Add(4 * procs)
    36  	for p := 0; p < procs; p++ {
    37  		const iters = 1e3
    38  		go func() {
    39  			trace.WithRegion(context.Background(), "special", func() {
    40  				for i := 0; i < iters; i++ {
    41  					runtime.Gosched()
    42  					c0 <- 0
    43  				}
    44  				done.Done()
    45  			})
    46  		}()
    47  		go func() {
    48  			trace.WithRegion(context.Background(), "special", func() {
    49  				for i := 0; i < iters; i++ {
    50  					runtime.Gosched()
    51  					<-c0
    52  				}
    53  				done.Done()
    54  			})
    55  		}()
    56  		go func() {
    57  			trace.WithRegion(context.Background(), "special", func() {
    58  				for i := 0; i < iters; i++ {
    59  					runtime.Gosched()
    60  					select {
    61  					case c1 <- 0:
    62  					case c2 <- 0:
    63  					}
    64  				}
    65  				done.Done()
    66  			})
    67  		}()
    68  		go func() {
    69  			trace.WithRegion(context.Background(), "special", func() {
    70  				for i := 0; i < iters; i++ {
    71  					runtime.Gosched()
    72  					select {
    73  					case <-c1:
    74  					case <-c2:
    75  					}
    76  				}
    77  				done.Done()
    78  			})
    79  		}()
    80  	}
    81  	done.Wait()
    82  
    83  	trace.Stop()
    84  }
    85  

View as plain text