diff options
author | Ian Lance Taylor <iant@golang.org> | 2022-02-11 14:53:56 -0800 |
---|---|---|
committer | Ian Lance Taylor <iant@golang.org> | 2022-02-11 15:01:19 -0800 |
commit | 8dc2499aa62f768c6395c9754b8cabc1ce25c494 (patch) | |
tree | 43d7fd2bbfd7ad8c9625a718a5e8718889351994 /libgo/go/context | |
parent | 9a56779dbc4e2d9c15be8d31e36f2f59be7331a8 (diff) | |
download | gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.zip gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.tar.gz gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.tar.bz2 |
libgo: update to Go1.18beta2
gotools/
* Makefile.am (go_cmd_cgo_files): Add ast_go118.go
(check-go-tool): Copy golang.org/x/tools directories.
* Makefile.in: Regenerate.
Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/384695
Diffstat (limited to 'libgo/go/context')
-rw-r--r-- | libgo/go/context/benchmark_test.go | 36 | ||||
-rw-r--r-- | libgo/go/context/context.go | 44 | ||||
-rw-r--r-- | libgo/go/context/context_test.go | 20 |
3 files changed, 81 insertions, 19 deletions
diff --git a/libgo/go/context/benchmark_test.go b/libgo/go/context/benchmark_test.go index 69d75ff..144f473 100644 --- a/libgo/go/context/benchmark_test.go +++ b/libgo/go/context/benchmark_test.go @@ -152,3 +152,39 @@ func BenchmarkContextCancelDone(b *testing.B) { } }) } + +func BenchmarkDeepValueNewGoRoutine(b *testing.B) { + for _, depth := range []int{10, 20, 30, 50, 100} { + ctx := Background() + for i := 0; i < depth; i++ { + ctx = WithValue(ctx, i, i) + } + + b.Run(fmt.Sprintf("depth=%d", depth), func(b *testing.B) { + for i := 0; i < b.N; i++ { + var wg sync.WaitGroup + wg.Add(1) + go func() { + defer wg.Done() + ctx.Value(-1) + }() + wg.Wait() + } + }) + } +} + +func BenchmarkDeepValueSameGoRoutine(b *testing.B) { + for _, depth := range []int{10, 20, 30, 50, 100} { + ctx := Background() + for i := 0; i < depth; i++ { + ctx = WithValue(ctx, i, i) + } + + b.Run(fmt.Sprintf("depth=%d", depth), func(b *testing.B) { + for i := 0; i < b.N; i++ { + ctx.Value(-1) + } + }) + } +} diff --git a/libgo/go/context/context.go b/libgo/go/context/context.go index 733c5f5..cf010b2 100644 --- a/libgo/go/context/context.go +++ b/libgo/go/context/context.go @@ -150,7 +150,7 @@ type Context interface { // u, ok := ctx.Value(userKey).(*User) // return u, ok // } - Value(key interface{}) interface{} + Value(key any) any } // Canceled is the error returned by Context.Err when the context is canceled. @@ -182,7 +182,7 @@ func (*emptyCtx) Err() error { return nil } -func (*emptyCtx) Value(key interface{}) interface{} { +func (*emptyCtx) Value(key any) any { return nil } @@ -348,11 +348,11 @@ type cancelCtx struct { err error // set to non-nil by the first cancel call } -func (c *cancelCtx) Value(key interface{}) interface{} { +func (c *cancelCtx) Value(key any) any { if key == &cancelCtxKey { return c } - return c.Context.Value(key) + return value(c.Context, key) } func (c *cancelCtx) Done() <-chan struct{} { @@ -520,7 +520,7 @@ func WithTimeout(parent Context, timeout time.Duration) (Context, CancelFunc) { // interface{}, context keys often have concrete type // struct{}. Alternatively, exported context key variables' static // type should be a pointer or interface. -func WithValue(parent Context, key, val interface{}) Context { +func WithValue(parent Context, key, val any) Context { if parent == nil { panic("cannot create context from nil parent") } @@ -537,13 +537,13 @@ func WithValue(parent Context, key, val interface{}) Context { // delegates all other calls to the embedded Context. type valueCtx struct { Context - key, val interface{} + key, val any } // stringify tries a bit to stringify v, without using fmt, since we don't // want context depending on the unicode tables. This is only used by // *valueCtx.String(). -func stringify(v interface{}) string { +func stringify(v any) string { switch s := v.(type) { case stringer: return s.String() @@ -559,9 +559,35 @@ func (c *valueCtx) String() string { ", val " + stringify(c.val) + ")" } -func (c *valueCtx) Value(key interface{}) interface{} { +func (c *valueCtx) Value(key any) any { if c.key == key { return c.val } - return c.Context.Value(key) + return value(c.Context, key) +} + +func value(c Context, key any) any { + for { + switch ctx := c.(type) { + case *valueCtx: + if key == ctx.key { + return ctx.val + } + c = ctx.Context + case *cancelCtx: + if key == &cancelCtxKey { + return c + } + c = ctx.Context + case *timerCtx: + if key == &cancelCtxKey { + return &ctx.cancelCtx + } + c = ctx.Context + case *emptyCtx: + return nil + default: + return c.Value(key) + } + } } diff --git a/libgo/go/context/context_test.go b/libgo/go/context/context_test.go index a2e2324..8673c0f 100644 --- a/libgo/go/context/context_test.go +++ b/libgo/go/context/context_test.go @@ -16,21 +16,21 @@ import ( type testingT interface { Deadline() (time.Time, bool) - Error(args ...interface{}) - Errorf(format string, args ...interface{}) + Error(args ...any) + Errorf(format string, args ...any) Fail() FailNow() Failed() bool - Fatal(args ...interface{}) - Fatalf(format string, args ...interface{}) + Fatal(args ...any) + Fatalf(format string, args ...any) Helper() - Log(args ...interface{}) - Logf(format string, args ...interface{}) + Log(args ...any) + Logf(format string, args ...any) Name() string Parallel() - Skip(args ...interface{}) + Skip(args ...any) SkipNow() - Skipf(format string, args ...interface{}) + Skipf(format string, args ...any) Skipped() bool } @@ -553,7 +553,7 @@ func testLayers(t testingT, seed int64, testTimeout bool) { t.Parallel() r := rand.New(rand.NewSource(seed)) - errorf := func(format string, a ...interface{}) { + errorf := func(format string, a ...any) { t.Errorf(fmt.Sprintf("seed=%d: %s", seed, format), a...) } const ( @@ -691,7 +691,7 @@ func XTestInvalidDerivedFail(t testingT) { } } -func recoveredValue(fn func()) (v interface{}) { +func recoveredValue(fn func()) (v any) { defer func() { v = recover() }() fn() return |