From: Carlo Alberto Ferraris Date: Tue, 6 Dec 2022 05:45:04 +0000 (+0900) Subject: context: reduce init-time allocations X-Git-Tag: go1.21rc1~1592 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6e5c26084f9f3bc910181854a4ff20851188e222;p=gostls13.git context: reduce init-time allocations Small cleanup to remove a couple of needless global variables. Instead of relying on two instances of emptyCtx having different addresses, we use different types. For #26775 Change-Id: I0bc4813e94226f7b3f52bf4b1b3c3a3bbbebcc9e Reviewed-on: https://go-review.googlesource.com/c/go/+/455455 Reviewed-by: Damien Neil TryBot-Result: Gopher Robot Run-TryBot: Ian Lance Taylor Reviewed-by: Sameer Ajmani --- diff --git a/src/context/context.go b/src/context/context.go index d6ed7443e9..c60179e70f 100644 --- a/src/context/context.go +++ b/src/context/context.go @@ -172,47 +172,44 @@ func (deadlineExceededError) Error() string { return "context deadline exceede func (deadlineExceededError) Timeout() bool { return true } func (deadlineExceededError) Temporary() bool { return true } -// An emptyCtx is never canceled, has no values, and has no deadline. It is not -// struct{}, since vars of this type must have distinct addresses. -type emptyCtx int +// An emptyCtx is never canceled, has no values, and has no deadline. +// It is the common base of backgroundCtx and todoCtx. +type emptyCtx struct{} -func (*emptyCtx) Deadline() (deadline time.Time, ok bool) { +func (emptyCtx) Deadline() (deadline time.Time, ok bool) { return } -func (*emptyCtx) Done() <-chan struct{} { +func (emptyCtx) Done() <-chan struct{} { return nil } -func (*emptyCtx) Err() error { +func (emptyCtx) Err() error { return nil } -func (*emptyCtx) Value(key any) any { +func (emptyCtx) Value(key any) any { return nil } -func (e *emptyCtx) String() string { - switch e { - case background: - return "context.Background" - case todo: - return "context.TODO" - } - return "unknown empty Context" +type backgroundCtx struct{ emptyCtx } + +func (backgroundCtx) String() string { + return "context.Background" } -var ( - background = new(emptyCtx) - todo = new(emptyCtx) -) +type todoCtx struct{ emptyCtx } + +func (todoCtx) String() string { + return "context.TODO" +} // Background returns a non-nil, empty Context. It is never canceled, has no // values, and has no deadline. It is typically used by the main function, // initialization, and tests, and as the top-level Context for incoming // requests. func Background() Context { - return background + return backgroundCtx{} } // TODO returns a non-nil, empty Context. Code should use context.TODO when @@ -220,7 +217,7 @@ func Background() Context { // surrounding function has not yet been extended to accept a Context // parameter). func TODO() Context { - return todo + return todoCtx{} } // A CancelFunc tells an operation to abandon its work. @@ -653,7 +650,7 @@ func value(c Context, key any) any { return &ctx.cancelCtx } c = ctx.Context - case *emptyCtx: + case backgroundCtx, todoCtx: return nil default: return c.Value(key)