diff --git a/examples/block-bias/block.pb.gz b/examples/block-bias/block.pb.gz new file mode 100644 index 0000000..09e0779 Binary files /dev/null and b/examples/block-bias/block.pb.gz differ diff --git a/examples/block-bias/go.mod b/examples/block-bias/go.mod new file mode 100644 index 0000000..08e0478 --- /dev/null +++ b/examples/block-bias/go.mod @@ -0,0 +1,5 @@ +module github.com/felixge/go-profiler-notes/examples/block-bias + +go 1.15 + +require golang.org/x/sync v0.0.0-20201207232520-09787c993a3a diff --git a/examples/block-bias/go.sum b/examples/block-bias/go.sum new file mode 100644 index 0000000..5f7eb37 --- /dev/null +++ b/examples/block-bias/go.sum @@ -0,0 +1,2 @@ +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a h1:DcqTD9SDLc+1P/r1EmRBwnVsrOwW+kk2vWf9n+1sGhs= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= diff --git a/examples/block-bias/main.go b/examples/block-bias/main.go new file mode 100644 index 0000000..1dd12dc --- /dev/null +++ b/examples/block-bias/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "fmt" + "os" + "runtime" + "runtime/pprof" + "sync" + "time" +) + +func main() { + if err := run(); err != nil { + fmt.Fprintln(os.Stderr, err) + os.Exit(1) + } +} + +var ( + fastEventDuration = 1 * time.Millisecond + slowEventDuration = 1 * fastEventDuration +) + +func run() error { + runtime.SetBlockProfileRate(int(slowEventDuration.Nanoseconds())) + + var ( + done = make(chan struct{}) + wg = &sync.WaitGroup{} + ) + wg.Add(1) + go func() { + defer wg.Done() + slowEvent(done) + }() + wg.Add(1) + go func() { + defer wg.Done() + fastEvent(done) + }() + time.Sleep(1 * time.Second) + close(done) + wg.Wait() + + f, err := os.Create("block.pb.gz") + if err != nil { + return err + } + defer f.Close() + if err := pprof.Lookup("block").WriteTo(f, 0); err != nil { + return err + } + return nil +} + +func slowEvent(done chan struct{}) error { + return simulateBlockEvents(slowEventDuration, done) +} + +func fastEvent(done chan struct{}) error { + return simulateBlockEvents(fastEventDuration, done) +} + +func simulateBlockEvents(duration time.Duration, done chan struct{}) error { + ticker := time.NewTicker(duration) + defer ticker.Stop() + for { + select { + case <-ticker.C: + // do nothing + case <-done: + return nil + } + } +}