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 13package main 14 15import ( 16 "context" 17 "log" 18 "os" 19 "runtime" 20 "runtime/trace" 21 "sync" 22) 23 24func 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