aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/context
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-02-11 14:53:56 -0800
committerIan Lance Taylor <iant@golang.org>2022-02-11 15:01:19 -0800
commit8dc2499aa62f768c6395c9754b8cabc1ce25c494 (patch)
tree43d7fd2bbfd7ad8c9625a718a5e8718889351994 /libgo/go/context
parent9a56779dbc4e2d9c15be8d31e36f2f59be7331a8 (diff)
downloadgcc-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.go36
-rw-r--r--libgo/go/context/context.go44
-rw-r--r--libgo/go/context/context_test.go20
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