The Go programming language
Go to file
Cherry Mui 59b7d40774 [release-branch.go1.23] runtime: update and restore g0 stack bounds at cgocallback
Currently, at a cgo callback where there is already a Go frame on
the stack (i.e. C->Go->C->Go), we require that at the inner Go
callback the SP is within the g0's stack bounds set by a previous
callback. This is to prevent that the C code switches stack while
having a Go frame on the stack, which we don't really support. But
this could also happen when we cannot get accurate stack bounds,
e.g. when pthread_getattr_np is not available. Since the stack
bounds are just estimates based on the current SP, if there are
multiple C->Go callbacks with various stack depth, it is possible
that the SP of a later callback falls out of a previous call's
estimate. This leads to runtime throw in a seemingly reasonable
program.

This CL changes it to save the old g0 stack bounds at cgocallback,
update the bounds, and restore the old bounds at return. So each
callback will get its own stack bounds based on the current SP,
and when it returns, the outer callback has the its old stack
bounds restored.

Also, at a cgo callback when there is no Go frame on the stack,
we currently always get new stack bounds. We do this because if
we can only get estimated bounds based on the SP, and the stack
depth varies a lot between two C->Go calls, the previous
estimates may be off and we fall out or nearly fall out of the
previous bounds. But this causes a performance problem: the
pthread API to get accurate stack bounds (pthread_getattr_np) is
very slow when called on the main thread. Getting the stack bounds
every time significantly slows down repeated C->Go calls on the
main thread.

This CL fixes it by "caching" the stack bounds if they are
accurate. I.e. at the second time Go calls into C, if the previous
stack bounds are accurate, and the current SP is in bounds, we can
be sure it is the same stack and we don't need to update the bounds.
This avoids the repeated calls to pthread_getattr_np. If we cannot
get the accurate bounds, we continue to update the stack bounds
based on the SP, and that operation is very cheap.

On a Linux/AMD64 machine with glibc:

name                     old time/op  new time/op  delta
CgoCallbackMainThread-8  96.4µs ± 3%   0.1µs ± 2%  -99.92%  (p=0.000 n=10+9)

Updates #68285.
Updates #68587.
Fixes #69988.

Change-Id: I3422badd5ad8ff63e1a733152d05fb7a44d5d435
Reviewed-on: https://go-review.googlesource.com/c/go/+/600296
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
(cherry picked from commit 76a8409eb8)
Reviewed-on: https://go-review.googlesource.com/c/go/+/635775
2024-12-13 11:18:11 -08:00
.github .github/ISSUE_TEMPLATE/03-gopls.yml: use textarea for gopls version 2024-05-24 17:09:04 +00:00
api crypto/tls: apply QUIC session event flag to QUICResumeSession events 2024-06-25 17:08:08 +00:00
doc doc/next: delete 2024-06-21 20:30:37 +00:00
lib/time lib/time: use consistent directory in mkzip usage message 2024-03-04 17:32:07 +00:00
misc misc/ios: rework exec wrapper to only support simulator 2024-06-18 16:32:49 +00:00
src [release-branch.go1.23] runtime: update and restore g0 stack bounds at cgocallback 2024-12-13 11:18:11 -08:00
test [release-branch.go1.23] cmd/link: generate Mach-O UUID when -B flag is specified 2024-10-30 17:03:35 +00:00
.gitattributes
.gitignore internal/platform,cmd/dist: export the list of supported platforms 2023-06-22 19:44:52 +00:00
CONTRIBUTING.md
LICENSE
PATENTS
README.md README: fix CC BY license name 2024-07-22 17:45:27 +00:00
SECURITY.md SECURITY.md: update the Reporting a Vulnerability link 2023-09-22 21:17:24 +00:00
VERSION [release-branch.go1.23] go1.23.4 2024-12-03 18:27:46 +00:00
codereview.cfg [release-branch.go1.23] update codereview.cfg for release-branch.go1.23 2024-06-18 21:25:28 +00:00
go.env cmd/go: additional doc-inspired tests and bug fixes 2023-06-06 19:18:46 +00:00

README.md

The Go Programming Language

Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.

Gopher image Gopher image by Renee French, licensed under Creative Commons 4.0 Attribution license.

Our canonical Git repository is located at https://go.googlesource.com/go. There is a mirror of the repository at https://github.com/golang/go.

Unless otherwise noted, the Go source files are distributed under the BSD-style license found in the LICENSE file.

Download and Install

Binary Distributions

Official binary distributions are available at https://go.dev/dl/.

After downloading a binary release, visit https://go.dev/doc/install for installation instructions.

Install From Source

If a binary distribution is not available for your combination of operating system and architecture, visit https://go.dev/doc/install/source for source installation instructions.

Contributing

Go is the work of thousands of contributors. We appreciate your help!

To contribute, please read the contribution guidelines at https://go.dev/doc/contribute.

Note that the Go project uses the issue tracker for bug reports and proposals only. See https://go.dev/wiki/Questions for a list of places to ask questions about the Go language.