context: reduce contention in cancelCtx.Done

Use an atomic.Value to hold the done channel.
Conveniently, we have a mutex handy to coordinate writes to it.

name                 old time/op  new time/op  delta
ContextCancelDone-8  67.5ns ±10%   2.2ns ±11%  -96.74%  (p=0.000 n=30+28)

Fixes #42564

Change-Id: I5d72e0e87fb221d4e230209e5fb4698bea4053c6
Reviewed-on: https://go-review.googlesource.com/c/go/+/288193
Trust: Josh Bleecher Snyder <josharian@gmail.com>
Trust: Sameer Ajmani <sameer@golang.org>
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Bryan C. Mills <bcmills@google.com>
This commit is contained in:
Josh Bleecher Snyder 2021-01-29 15:41:18 -08:00
parent 691ac806d2
commit ae1fa08e41
2 changed files with 33 additions and 14 deletions

View file

@ -5,6 +5,7 @@
package context_test
import (
"context"
. "context"
"fmt"
"runtime"
@ -138,3 +139,17 @@ func BenchmarkCheckCanceled(b *testing.B) {
}
})
}
func BenchmarkContextCancelDone(b *testing.B) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
select {
case <-ctx.Done():
default:
}
}
})
}