aboutsummaryrefslogtreecommitdiff
path: root/src/sync
AgeCommit message (Collapse)Author
2025-06-30sync: disassociate WaitGroups from bubbles on WaitDamien Neil
Fix a race condition in disassociating a WaitGroup in a synctest bubble from its bubble. We previously disassociated the WaitGroup when count becomes 0, but this causes problems when an Add call setting count to 0 races with one incrementing the count. Instead, disassociate a WaitGroup from its bubble when Wait returns. Wait must not be called concurrently with an Add call with a positive delta and a 0 count, so we know that the disassociation will not race with an Add call trying to create a new association. Fixes #74386 Change-Id: I9b519519921f7691869a64a245a5ee65d071d054 Reviewed-on: https://go-review.googlesource.com/c/go/+/684635 Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-06-10testing/synctest, runtime: avoid panic when using linker-alloc WG from bubbleDamien Neil
We associate WaitGroups with synctest bubbles by attaching a special to the WaitGroup. It is not possible to attach a special to a linker-allocated value, such as: var wg sync.WaitGroup Avoid panicking when accessing a linker-allocated WaitGroup from a bubble. We have no way to associate these WaitGroups with a bubble, so just treat them as always unbubbled. This is probably fine, since the WaitGroup was always created outside the bubble in this case. Fixes #74005 Change-Id: Ic71514b0b8d0cecd62e45cc929ffcbeb16f54a55 Reviewed-on: https://go-review.googlesource.com/c/go/+/679695 Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-05-29runtime, internal/synctest, sync: associate WaitGroups with bubblesDamien Neil
Add support to internal/synctest for managing associations between arbitrary pointers and synctest bubbles. (Implemented internally to the runtime package by attaching a special to the pointer.) Associate WaitGroups with bubbles. Since WaitGroups don't have a constructor, perform the association when Add is called. All Add calls must be made from within the same bubble, or outside any bubble. When a bubbled goroutine calls WaitGroup.Wait, the wait is durably blocking iff the WaitGroup is associated with the current bubble. Change-Id: I77e2701e734ac2fa2b32b28d5b0c853b7b2825c9 Reviewed-on: https://go-review.googlesource.com/c/go/+/676656 Reviewed-by: Michael Knyszek <mknyszek@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Damien Neil <dneil@google.com>
2025-05-16sync: set GOMAXPROCS to 1 in TestPoolGCMichael Anthony Knyszek
This test expects to be able to drain a Pool using only Get. This isn't actually possible in the general case, since a pooled value could get stuck in some P's private slot. However, if GOMAXPROCS=1, there's only 1 P we could be running on, so getting stuck becomes impossible. This test isn't checking any concurrent properties of Pool, so this is fine. Just set GOMAXPROCS=1 for this one particular test. Fixes #73728. Change-Id: I9053e28118060650f2cd7d0d58f5a86d630b36f7 Reviewed-on: https://go-review.googlesource.com/c/go/+/673375 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com>
2025-05-14sync: use blockUntilCleanupQueueEmpty instead of busy-looping in testsMichael Anthony Knyszek
testPool currently does the old-style busy loop to wait until cleanups have executed. Clean this up by using the linkname'd blockUntilCleanupQueueEmpty. For #73642. Change-Id: Ie0c2614db858a984f25b33a805dc52948069eb52 Reviewed-on: https://go-review.googlesource.com/c/go/+/671675 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2025-05-08runtime: schedule cleanups across multiple goroutinesMichael Anthony Knyszek
This change splits the finalizer and cleanup queues and implements a new lock-free blocking queue for cleanups. The basic design is as follows: The cleanup queue is organized in fixed-sized blocks. Individual cleanup functions are queued, but only whole blocks are dequeued. Enqueuing cleanups places them in P-local cleanup blocks. These are flushed to the full list as they get full. Cleanups can only be enqueued by an active sweeper. Dequeuing cleanups always dequeues entire blocks from the full list. Cleanup blocks can be dequeued and executed at any time. The very last active sweeper in the sweep phase is responsible for flushing all local cleanup blocks to the full list. It can do this without any synchronization because the next GC can't start yet, so we can be very certain that nobody else will be accessing the local blocks. Cleanup blocks are stored off-heap because the need to be allocated by the sweeper, which is called from heap allocation paths. As a result, the GC treats cleanup blocks as roots, just like finalizer blocks. Flushes to the full list signal to the scheduler that cleanup goroutines should be awoken. Every time the scheduler goes to wake up a cleanup goroutine and there were more signals than goroutines to wake, it then forwards this signal to runtime.AddCleanup, so that it creates another goroutine the next time it is called, up to gomaxprocs goroutines. The signals here are a little convoluted, but exist because the sweeper and the scheduler cannot safely create new goroutines. For #71772. For #71825. Change-Id: Ie839fde2b67e1b79ac1426be0ea29a8d923a62cc Reviewed-on: https://go-review.googlesource.com/c/go/+/650697 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
2025-05-01sync: WaitGroup.Go: document that f must not panicAlan Donovan
Fixes #63796 Change-Id: Ib11d32574011e13aab3a0ad504f0d10009627503 Reviewed-on: https://go-review.googlesource.com/c/go/+/667695 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Damien Neil <dneil@google.com> Commit-Queue: Alan Donovan <adonovan@google.com> Auto-Submit: Alan Donovan <adonovan@google.com>
2025-04-25sync: tidy WaitGroup documentation, add WaitGroup.Go exampleAustin Clements
This reframes the WaitGroup documentation with Go at its center and Add/Done as more "advanced" features. Updates #63796 Change-Id: I8101972626fdb00c6f7fb185b685227823d10db1 Reviewed-on: https://go-review.googlesource.com/c/go/+/662975 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alan Donovan <adonovan@google.com> Auto-Submit: Austin Clements <austin@google.com> Reviewed-by: Carlos Amedee <carlos@golang.org>
2025-04-24sync/atomic: document that atomic types should not be copiedMateusz Poliwczak
Change-Id: I3c557d02cd676a389b5c5ea70ed92c8959041e3b GitHub-Last-Rev: 8732da19a64853834ca155cafc1d7b2967290c31 GitHub-Pull-Request: golang/go#63256 Reviewed-on: https://go-review.googlesource.com/c/go/+/531375 Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Sean Liao <sean@liao.dev> Reviewed-by: Sean Liao <sean@liao.dev>
2025-04-22sync: use atomic.Bool for Once.donePrabhav Dogra
Updated the use of atomic.Uint32 to atomic.Bool for sync package. Change-Id: Ib8da66fea86ef06e1427ac5118016b96fbcda6b1 GitHub-Last-Rev: d36e0f431fcde988f90badf86bbf04a18a411947 GitHub-Pull-Request: golang/go#73447 Reviewed-on: https://go-review.googlesource.com/c/go/+/666895 Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: Keith Randall <khr@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Jorropo <jorropo.pgm@gmail.com>
2025-04-04sync: add WaitGroup.Goqiulaidongfeng
Fixes #63796 Change-Id: I2a941275dd64ef858cbf02d31a759fdc5c082ceb Reviewed-on: https://go-review.googlesource.com/c/go/+/662635 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Alan Donovan <adonovan@google.com> Auto-Submit: Carlos Amedee <carlos@golang.org> Reviewed-by: Carlos Amedee <carlos@golang.org>
2025-03-05sync: document behavior of Map.Delete when key is not presentFilippo Valsorda
Change-Id: I6a6a465631e91141a5fcc9c04a7df0dc47780731 Reviewed-on: https://go-review.googlesource.com/c/go/+/643955 Reviewed-by: Daniel McCarney <daniel@binaryparadox.net> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Junyang Shao <shaojunyang@google.com> Reviewed-by: Michael Pratt <mpratt@google.com>
2025-02-26sync: don't keep func alive after OnceFunc panicsMateusz Poliwczak
This moves the f = nil assignment to the defer statement, so that in case the functions panics, the f func is not referenced anymore. Change-Id: I3e53b90a10f21741e26602270822c8a75679f163 GitHub-Last-Rev: bda01100c6d48d1b0ca3e1baefef4d592cca1fee GitHub-Pull-Request: golang/go#68636 Reviewed-on: https://go-review.googlesource.com/c/go/+/601240 Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com>
2025-02-25sync: reduce OnceFunc (and variants) heap allocationsBrian Byrne
The lifetime of the variables are identical; capture them in a single struct to avoid individual allocations. The inner closure can also avoid allocation by using the capture of the outer closure. Escape analysis for OnceValues: /go/src/sync/oncefunc.go:74:29: moved to heap: sync.f /go/src/sync/oncefunc.go:76:3: moved to heap: sync.once /go/src/sync/oncefunc.go:77:3: moved to heap: sync.valid /go/src/sync/oncefunc.go:78:3: moved to heap: sync.p /go/src/sync/oncefunc.go:79:3: moved to heap: sync.r1 /go/src/sync/oncefunc.go:80:3: moved to heap: sync.r2 /go/src/sync/oncefunc.go:82:7: func literal escapes to heap /go/src/sync/oncefunc.go:83:9: func literal does not escape /go/src/sync/oncefunc.go:93:9: func literal escapes to heap After provided changes: /go/src/sync/oncefunc.go:86:2: moved to heap: sync.d /go/src/sync/oncefunc.go:96:9: func literal escapes to heap /go/src/sync/oncefunc.go:99:13: func literal does not escape /go/src/sync/oncefunc.go:100:10: func literal does not escape Change-Id: Ib06e650fd427b57e0bdbdf1fe759fe436104ff79 Reviewed-on: https://go-review.googlesource.com/c/go/+/601596 Auto-Submit: Austin Clements <austin@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Austin Clements <austin@google.com>
2025-02-24all: use testenv.Executable instead of os.Executable and os.Args[0]qmuntal
In test files, using testenv.Executable is more reliable than os.Executable or os.Args[0]. Change-Id: I88e577efeabc20d02ada27bf706ae4523129128e Reviewed-on: https://go-review.googlesource.com/c/go/+/651955 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2025-02-14sync: use runtime.AddCleanup instead of runtime.SetFinalizerCarlos Amedee
This changes the use of finalizers to the cleanup implementation in tests. Updates #70907 Change-Id: I7d7289999a83fa53f538698f34294f7d9651c921 Reviewed-on: https://go-review.googlesource.com/c/go/+/640735 Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-12-04sync: document RWMutex locks cannot be upgraded / downgradedSean Liao
Fixes #38859 Change-Id: I9f4f6fa4cb529aaadfb3812e3a5c0da982a95f68 Reviewed-on: https://go-review.googlesource.com/c/go/+/633415 Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2024-11-19internal/synctest: new package for testing concurrent codeDamien Neil
Add an internal (for now) implementation of testing/synctest. The synctest.Run function executes a tree of goroutines in an isolated environment using a fake clock. The synctest.Wait function allows a test to wait for all other goroutines within the test to reach a blocking point. For #67434 For #69687 Change-Id: Icb39e54c54cece96517e58ef9cfb18bf68506cfc Reviewed-on: https://go-review.googlesource.com/c/go/+/591997 Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-11-18sync: make HashTrieMap[any, any] the default implementation of MapMichael Anthony Knyszek
This change adds a GOEXPERIMENT, synchashtriemap, which replaces the internals of a sync.Map with internal/sync.HashTrieMap[any, any]. The main purpose behind this change is improved performance. Across almost every benchmark, HashTrieMap[any, any] performs better than Map. Also, relax TestMapClearNoAllocations to allow for one allocation. Currently, the HashTrieMap allocates a new empty root node and stores it: that's the whole clear operation. At the cost of some complexity, we could allow Clear to have zero allocations by clearing the root node. The complexity comes down to allowing threads to race to install a new root node *or* creating a top-level mutex for installing a root node. But I'm not sure this is worth it. Whether Clear or some other operation takes the hit for allocating a single node almost certainly doesn't matter. And Clear is still much, much faster in the new implementation than the old, so I don't consider this a regression. Change-Id: I939aa70a0edf2e850cedbea239aaf29a11a77b79 Reviewed-on: https://go-review.googlesource.com/c/go/+/608335 Auto-Submit: Michael Knyszek <mknyszek@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com>
2024-11-18sync: add HashTrieMap to Map tests and benchmarksMichael Anthony Knyszek
Also, rename Map benchmarks to make them easier to single out via regexp. Change-Id: I4dcb066745aba1c340f56050d08539ae2976274d Reviewed-on: https://go-review.googlesource.com/c/go/+/606461 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
2024-11-18internal/sync: move sync.Mutex implementation into new packageMichael Anthony Knyszek
This CL refactors sync.Mutex such that its implementation lives in the new internal/sync package. The purpose of this change is to eventually reverse the dependency edge between internal/concurrent and sync, such that sync can depend on internal/concurrent (or really, its contents, which will likely end up in internal/sync). The only change made to the sync.Mutex code is the frame skip count for mutex profiling, so that the internal/sync frames are omitted in the profile. Change-Id: Ib3603d30e8e71508c4ea883a584ae2e51ce40c3f Reviewed-on: https://go-review.googlesource.com/c/go/+/594056 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Auto-Submit: Michael Knyszek <mknyszek@google.com>
2024-11-18sync: add explicit noCopy fields to Map, Mutex, and OnceMichael Anthony Knyszek
Following CLs will refactor Mutex and change the internals of Map. This ends up breaking tests in x/tools for the copylock vet check, because the error message changes. Let's insulate ourselves from such things permanently by adding an explicit noCopy field. We'll update the vet check to accept that as the problem, rather than depend on less explicit internals. We capture Once here too to clean up the error message as well. Change-Id: Iead985fc8ec9ef3ea5ff615f26dde17bb03aeadb Reviewed-on: https://go-review.googlesource.com/c/go/+/627777 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Michael Knyszek <mknyszek@google.com> Reviewed-by: Tim King <taking@google.com>
2024-11-15sync/atomic: make intrinsics noescape except 64bits op on 32bits arch and ↵Jorropo
unsafe.Pointer Fixes #16241 I made 64 bits op on 32 bits arches still leak since it was kinda promised. The promised leaks were wider than this but I don't belive it's effect can be observed in an breaking maner without using unsafe the way it's currently setup. Change-Id: I66d8df47bfe49bce3efa64ac668a2a55f70733a3 Reviewed-on: https://go-review.googlesource.com/c/go/+/462298 Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
2024-07-11all: make struct comments match struct namescuishuang
Change-Id: I011f66854a9af5f3baa20abebd4b315c15db571f Reviewed-on: https://go-review.googlesource.com/c/go/+/596715 Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: shuang cui <imcusg@gmail.com> Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Commit-Queue: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-07-01sync: refer to Locker interface methods in RWMutex.RLocker docDmitri Shuralyov
The methods being implemented are part of the Locker interface, not the RWMutex struct. Fixes #68250. Change-Id: I609c4d5c44e90a12914a8678971ba295519cc265 Reviewed-on: https://go-review.googlesource.com/c/go/+/595875 Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Than McIntosh <thanm@google.com>
2024-06-21sync/atomic: correct result names for Or methodsAustin Clements
A few of the new Or methods of the atomic types use "new" as the name for the result value, but it actually returns the old value. Fix this by renaming the result values to "old". Updates #61395. Change-Id: Ib08db9964f5dfe91929f216d50ff0c9cc891ee49 Reviewed-on: https://go-review.googlesource.com/c/go/+/593855 Reviewed-by: Keith Randall <khr@google.com> Reviewed-by: Keith Randall <khr@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Austin Clements <austin@google.com> Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
2024-06-07sync: include links to the Go memory model in package documentationRodrigo Orselli
The lack of links to https://go.dev/ref/mem in the sync package documentation makes it difficult to read for people who have no previous knowledge of that page. This PR includes the links where needed. Fixes #67891 Change-Id: I0e1344cc6d7b702f4cb2e55fe0fcee3eb089391a GitHub-Last-Rev: 427cf58aaeaae2e4b060248dd592e5fe8c6b7df4 GitHub-Pull-Request: golang/go#67892 Reviewed-on: https://go-review.googlesource.com/c/go/+/591395 Reviewed-by: Michael Knyszek <mknyszek@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-29all: document legacy //go:linkname for modules with ≥100 dependentsRuss Cox
For #67401. Change-Id: I015408a3f437c1733d97160ef2fb5da6d4efcc5c Reviewed-on: https://go-review.googlesource.com/c/go/+/587598 Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Russ Cox <rsc@golang.org>
2024-05-23all: document legacy //go:linkname for modules with ≥500 dependentsRuss Cox
For #67401. Change-Id: I7dd28c3b01a1a647f84929d15412aa43ab0089ee Reviewed-on: https://go-review.googlesource.com/c/go/+/587575 Reviewed-by: Cherry Mui <cherryyz@google.com> Auto-Submit: Russ Cox <rsc@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-05-23all: change from sort functions to slices functions where feasibleIan Lance Taylor
Doing this because the slices functions are slightly faster and slightly easier to use. It also removes one dependency layer. This CL does not change packages that are used during bootstrap, as the bootstrap compiler does not have the required slices functions. It does not change the go/scanner package because the ErrorList Len, Swap, and Less methods are part of the Go 1 API. Change-Id: If52899be791c829198e11d2408727720b91ebe8a Reviewed-on: https://go-review.googlesource.com/c/go/+/587655 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Commit-Queue: Ian Lance Taylor <iant@google.com> Reviewed-by: Damien Neil <dneil@google.com>
2024-05-17sync/atomic: public And/Or ops and race instrumentationMauri de Souza Meneguzzo
This CL implements the new sync/atomic AND and OR apis as well as their race counterparts. Fixes #61395 Change-Id: I294eefe4b3ac27bc4ed237edcbfa88a8c646d86f GitHub-Last-Rev: f174297007c7b81b1ff4a687ef23d955a3ffd4db GitHub-Pull-Request: golang/go#64331 Reviewed-on: https://go-review.googlesource.com/c/go/+/544455 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Austin Clements <austin@google.com> Auto-Submit: Austin Clements <austin@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Keith Randall <khr@google.com>
2024-05-17all: add push linknames to allow legacy pull linknamesCherry Mui
CL 585358 adds restrictions to disallow pull-only linknames (currently off by default). Currently, there are quite some pull- only linknames in user code in the wild. In order not to break those, we add push linknames to allow them to be pulled. This CL includes linknames found in a large code corpus (thanks Matthew Dempsky and Michael Pratt for the analysis!), that are not currently linknamed. Updates #67401. Change-Id: I32f5fc0c7a6abbd7a11359a025cfa2bf458fe767 Reviewed-on: https://go-review.googlesource.com/c/go/+/586137 Reviewed-by: Russ Cox <rsc@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-04-23sync: add examples for OnceValue and OnceValuesAustin Clements
Updates #56102. Change-Id: I2ee2dbc43b4333511d9d23752fdc574dfbf5f5bd Reviewed-on: https://go-review.googlesource.com/c/go/+/481062 Reviewed-by: Andrew Gerrand <adg@golang.org> Auto-Submit: Austin Clements <austin@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Joedian Reid <joedian@google.com>
2024-03-25runtime: migrate internal/atomic to internal/runtimeAndy Pan
For #65355 Change-Id: I65dd090fb99de9b231af2112c5ccb0eb635db2be Reviewed-on: https://go-review.googlesource.com/c/go/+/560155 Reviewed-by: David Chase <drchase@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ibrahim Bazoka <ibrahimbazoka729@gmail.com> Auto-Submit: Emmanuel Odeke <emmanuel@orijtech.com>
2024-03-21sync: name the Map.CompareAndSwap return valuePeter Collingbourne
The godoc for sync.Map.CompareAndSwap does not document the meaning of its return value. Document it by giving it a name. Change-Id: I50ad9c078a7885f5ce83489d66d138d491c35861 Reviewed-on: https://go-review.googlesource.com/c/go/+/572657 Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-02-28all: run go fmtsivchari
I ran go fmt to fix format on the entire repository. Change-Id: I2f09166b6b8ba0ffb0ba27f6500efb0ea4cf21ff Reviewed-on: https://go-review.googlesource.com/c/go/+/566835 Reviewed-by: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Carlos Amedee <carlos@golang.org> Auto-Submit: Ian Lance Taylor <iant@golang.org>
2024-02-26sync: add available godoc linkcui fliter
Change-Id: I9bc5fd29b0eec8ceadcfee2116de5e7524ef92c2 Reviewed-on: https://go-review.googlesource.com/c/go/+/539617 Auto-Submit: Ian Lance Taylor <iant@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Pratt <mpratt@google.com> Run-TryBot: shuang cui <imcusg@gmail.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@google.com>
2024-02-26sync: simplify the code with atomic.Pointerapocelipes
Change-Id: I79797be6b385c9927d68350334d7f7387007085f GitHub-Last-Rev: 3daa3b144f55f527d183d4ff35475ca4af3ee143 GitHub-Pull-Request: golang/go#65937 Reviewed-on: https://go-review.googlesource.com/c/go/+/566815 LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Dmitry Vyukov <dvyukov@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Commit-Queue: Ian Lance Taylor <iant@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com>
2024-02-01sync: update doc for Map.ClearJes Cok
Change-Id: I9bcc5c82321cbc93f1c7aafd1dadf4f6b862ccbd GitHub-Last-Rev: 818b95528f6beb6178b385953b49fbfbaeb31a82 GitHub-Pull-Request: golang/go#65429 Reviewed-on: https://go-review.googlesource.com/c/go/+/560396 Reviewed-by: Bryan Mills <bcmills@google.com> Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-02-01sync: add Map.ClearHiro
Fixes #61696 Change-Id: I0a31afd3bc433fc84280d56f2798bda10da61eba GitHub-Last-Rev: 17bedc864f1685178a42b59f7083677a6124f831 GitHub-Pull-Request: golang/go#61702 Reviewed-on: https://go-review.googlesource.com/c/go/+/515015 Auto-Submit: Bryan Mills <bcmills@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Reviewed-by: qiulaidongfeng <2645477756@qq.com> Reviewed-by: Bryan Mills <bcmills@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2024-01-08sync: use map[any]any instead of map[interface{}]interface{} in the godocsivchari
It's shorter and clearer. Change-Id: Ibfbe5a7f8d70fa884691ba9858a2c9b2122d9c50 Reviewed-on: https://go-review.googlesource.com/c/go/+/531475 Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Daniel Martí <mvdan@mvdan.cc> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>
2023-12-05math/rand, math/rand/v2: use ChaCha8 for global randRuss Cox
Move ChaCha8 code into internal/chacha8rand and use it to implement runtime.rand, which is used for the unseeded global source for both math/rand and math/rand/v2. This also affects the calculation of the start point for iteration over very very large maps (when the 32-bit fastrand is not big enough). The benefit is that misuse of the global random number generators in math/rand and math/rand/v2 in contexts where non-predictable randomness is important for security reasons is no longer a security problem, removing a common mistake among programmers who are unaware of the different kinds of randomness. The cost is an extra 304 bytes per thread stored in the m struct plus 2-3ns more per random uint64 due to the more sophisticated algorithm. Using PCG looks like it would cost about the same, although I haven't benchmarked that. Before this, the math/rand and math/rand/v2 global generator was wyrand (https://github.com/wangyi-fudan/wyhash). For math/rand, using wyrand instead of the Mitchell/Reeds/Thompson ALFG was justifiable, since the latter was not any better. But for math/rand/v2, the global generator really should be at least as good as one of the well-studied, specific algorithms provided directly by the package, and it's not. (Wyrand is still reasonable for scheduling and cache decisions.) Good randomness does have a cost: about twice wyrand. Also rationalize the various runtime rand references. goos: linux goarch: amd64 pkg: math/rand/v2 cpu: AMD Ryzen 9 7950X 16-Core Processor │ bbb48afeb7.amd64 │ 5cf807d1ea.amd64 │ │ sec/op │ sec/op vs base │ ChaCha8-32 1.862n ± 2% 1.861n ± 2% ~ (p=0.825 n=20) PCG_DXSM-32 1.471n ± 1% 1.460n ± 2% ~ (p=0.153 n=20) SourceUint64-32 1.636n ± 2% 1.582n ± 1% -3.30% (p=0.000 n=20) GlobalInt64-32 2.087n ± 1% 3.663n ± 1% +75.54% (p=0.000 n=20) GlobalInt64Parallel-32 0.1042n ± 1% 0.2026n ± 1% +94.48% (p=0.000 n=20) GlobalUint64-32 2.263n ± 2% 3.724n ± 1% +64.57% (p=0.000 n=20) GlobalUint64Parallel-32 0.1019n ± 1% 0.1973n ± 1% +93.67% (p=0.000 n=20) Int64-32 1.771n ± 1% 1.774n ± 1% ~ (p=0.449 n=20) Uint64-32 1.863n ± 2% 1.866n ± 1% ~ (p=0.364 n=20) GlobalIntN1000-32 3.134n ± 3% 4.730n ± 2% +50.95% (p=0.000 n=20) IntN1000-32 2.489n ± 1% 2.489n ± 1% ~ (p=0.683 n=20) Int64N1000-32 2.521n ± 1% 2.516n ± 1% ~ (p=0.394 n=20) Int64N1e8-32 2.479n ± 1% 2.478n ± 2% ~ (p=0.743 n=20) Int64N1e9-32 2.530n ± 2% 2.514n ± 2% ~ (p=0.193 n=20) Int64N2e9-32 2.501n ± 1% 2.494n ± 1% ~ (p=0.616 n=20) Int64N1e18-32 3.227n ± 1% 3.205n ± 1% ~ (p=0.101 n=20) Int64N2e18-32 3.647n ± 1% 3.599n ± 1% ~ (p=0.019 n=20) Int64N4e18-32 5.135n ± 1% 5.069n ± 2% ~ (p=0.034 n=20) Int32N1000-32 2.657n ± 1% 2.637n ± 1% ~ (p=0.180 n=20) Int32N1e8-32 2.636n ± 1% 2.636n ± 1% ~ (p=0.763 n=20) Int32N1e9-32 2.660n ± 2% 2.638n ± 1% ~ (p=0.358 n=20) Int32N2e9-32 2.662n ± 2% 2.618n ± 2% ~ (p=0.064 n=20) Float32-32 2.272n ± 2% 2.239n ± 2% ~ (p=0.194 n=20) Float64-32 2.272n ± 1% 2.286n ± 2% ~ (p=0.763 n=20) ExpFloat64-32 3.762n ± 1% 3.744n ± 1% ~ (p=0.171 n=20) NormFloat64-32 3.706n ± 1% 3.655n ± 2% ~ (p=0.066 n=20) Perm3-32 32.93n ± 3% 34.62n ± 1% +5.13% (p=0.000 n=20) Perm30-32 202.9n ± 1% 204.0n ± 1% ~ (p=0.482 n=20) Perm30ViaShuffle-32 115.0n ± 1% 114.9n ± 1% ~ (p=0.358 n=20) ShuffleOverhead-32 112.8n ± 1% 112.7n ± 1% ~ (p=0.692 n=20) Concurrent-32 2.107n ± 0% 3.725n ± 1% +76.75% (p=0.000 n=20) goos: darwin goarch: arm64 pkg: math/rand/v2 │ bbb48afeb7.arm64 │ 5cf807d1ea.arm64 │ │ sec/op │ sec/op vs base │ ChaCha8-8 2.480n ± 0% 2.429n ± 0% -2.04% (p=0.000 n=20) PCG_DXSM-8 2.531n ± 0% 2.530n ± 0% ~ (p=0.877 n=20) SourceUint64-8 2.534n ± 0% 2.533n ± 0% ~ (p=0.732 n=20) GlobalInt64-8 2.172n ± 1% 4.794n ± 0% +120.67% (p=0.000 n=20) GlobalInt64Parallel-8 0.4320n ± 0% 0.9605n ± 0% +122.32% (p=0.000 n=20) GlobalUint64-8 2.182n ± 0% 4.770n ± 0% +118.58% (p=0.000 n=20) GlobalUint64Parallel-8 0.4307n ± 0% 0.9583n ± 0% +122.51% (p=0.000 n=20) Int64-8 4.107n ± 0% 4.104n ± 0% ~ (p=0.416 n=20) Uint64-8 4.080n ± 0% 4.080n ± 0% ~ (p=0.052 n=20) GlobalIntN1000-8 2.814n ± 2% 5.643n ± 0% +100.50% (p=0.000 n=20) IntN1000-8 4.141n ± 0% 4.139n ± 0% ~ (p=0.140 n=20) Int64N1000-8 4.140n ± 0% 4.140n ± 0% ~ (p=0.313 n=20) Int64N1e8-8 4.140n ± 0% 4.139n ± 0% ~ (p=0.103 n=20) Int64N1e9-8 4.139n ± 0% 4.140n ± 0% ~ (p=0.761 n=20) Int64N2e9-8 4.140n ± 0% 4.140n ± 0% ~ (p=0.636 n=20) Int64N1e18-8 5.266n ± 0% 5.326n ± 1% +1.14% (p=0.001 n=20) Int64N2e18-8 6.052n ± 0% 6.167n ± 0% +1.90% (p=0.000 n=20) Int64N4e18-8 8.826n ± 0% 9.051n ± 0% +2.55% (p=0.000 n=20) Int32N1000-8 4.127n ± 0% 4.132n ± 0% +0.12% (p=0.000 n=20) Int32N1e8-8 4.126n ± 0% 4.131n ± 0% +0.12% (p=0.000 n=20) Int32N1e9-8 4.127n ± 0% 4.132n ± 0% +0.12% (p=0.000 n=20) Int32N2e9-8 4.132n ± 0% 4.131n ± 0% ~ (p=0.017 n=20) Float32-8 4.109n ± 0% 4.105n ± 0% ~ (p=0.379 n=20) Float64-8 4.107n ± 0% 4.106n ± 0% ~ (p=0.867 n=20) ExpFloat64-8 5.339n ± 0% 5.383n ± 0% +0.82% (p=0.000 n=20) NormFloat64-8 5.735n ± 0% 5.737n ± 1% ~ (p=0.856 n=20) Perm3-8 26.65n ± 0% 26.80n ± 1% +0.58% (p=0.000 n=20) Perm30-8 194.8n ± 1% 197.0n ± 0% +1.18% (p=0.000 n=20) Perm30ViaShuffle-8 156.6n ± 0% 157.6n ± 1% +0.61% (p=0.000 n=20) ShuffleOverhead-8 124.9n ± 0% 125.5n ± 0% +0.52% (p=0.000 n=20) Concurrent-8 2.434n ± 3% 5.066n ± 0% +108.09% (p=0.000 n=20) goos: linux goarch: 386 pkg: math/rand/v2 cpu: AMD Ryzen 9 7950X 16-Core Processor │ bbb48afeb7.386 │ 5cf807d1ea.386 │ │ sec/op │ sec/op vs base │ ChaCha8-32 11.295n ± 1% 4.748n ± 2% -57.96% (p=0.000 n=20) PCG_DXSM-32 7.693n ± 1% 7.738n ± 2% ~ (p=0.542 n=20) SourceUint64-32 7.658n ± 2% 7.622n ± 2% ~ (p=0.344 n=20) GlobalInt64-32 3.473n ± 2% 7.526n ± 2% +116.73% (p=0.000 n=20) GlobalInt64Parallel-32 0.3198n ± 0% 0.5444n ± 0% +70.22% (p=0.000 n=20) GlobalUint64-32 3.612n ± 0% 7.575n ± 1% +109.69% (p=0.000 n=20) GlobalUint64Parallel-32 0.3168n ± 0% 0.5403n ± 0% +70.51% (p=0.000 n=20) Int64-32 7.673n ± 2% 7.789n ± 1% ~ (p=0.122 n=20) Uint64-32 7.773n ± 1% 7.827n ± 2% ~ (p=0.920 n=20) GlobalIntN1000-32 6.268n ± 1% 9.581n ± 1% +52.87% (p=0.000 n=20) IntN1000-32 10.33n ± 2% 10.45n ± 1% ~ (p=0.233 n=20) Int64N1000-32 10.98n ± 2% 11.01n ± 1% ~ (p=0.401 n=20) Int64N1e8-32 11.19n ± 2% 10.97n ± 1% ~ (p=0.033 n=20) Int64N1e9-32 11.06n ± 1% 11.08n ± 1% ~ (p=0.498 n=20) Int64N2e9-32 11.10n ± 1% 11.01n ± 2% ~ (p=0.995 n=20) Int64N1e18-32 15.23n ± 2% 15.04n ± 1% ~ (p=0.973 n=20) Int64N2e18-32 15.89n ± 1% 15.85n ± 1% ~ (p=0.409 n=20) Int64N4e18-32 18.96n ± 2% 19.34n ± 2% ~ (p=0.048 n=20) Int32N1000-32 10.46n ± 2% 10.44n ± 2% ~ (p=0.480 n=20) Int32N1e8-32 10.46n ± 2% 10.49n ± 2% ~ (p=0.951 n=20) Int32N1e9-32 10.28n ± 2% 10.26n ± 1% ~ (p=0.431 n=20) Int32N2e9-32 10.50n ± 2% 10.44n ± 2% ~ (p=0.249 n=20) Float32-32 13.80n ± 2% 13.80n ± 2% ~ (p=0.751 n=20) Float64-32 23.55n ± 2% 23.87n ± 0% ~ (p=0.408 n=20) ExpFloat64-32 15.36n ± 1% 15.29n ± 2% ~ (p=0.316 n=20) NormFloat64-32 13.57n ± 1% 13.79n ± 1% +1.66% (p=0.005 n=20) Perm3-32 45.70n ± 2% 46.99n ± 2% +2.81% (p=0.001 n=20) Perm30-32 399.0n ± 1% 403.8n ± 1% +1.19% (p=0.006 n=20) Perm30ViaShuffle-32 349.0n ± 1% 350.4n ± 1% ~ (p=0.909 n=20) ShuffleOverhead-32 322.3n ± 1% 323.8n ± 1% ~ (p=0.410 n=20) Concurrent-32 3.331n ± 1% 7.312n ± 1% +119.50% (p=0.000 n=20) For #61716. Change-Id: Ibdddeed85c34d9ae397289dc899e04d4845f9ed2 Reviewed-on: https://go-review.googlesource.com/c/go/+/516860 Reviewed-by: Michael Pratt <mpratt@google.com> Reviewed-by: Filippo Valsorda <filippo@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
2023-11-21sync: do not unnecessarily keep alive functions wrapped by ↵Carlo Alberto Ferraris
Once(Func|Value|Values) The function passed to OnceFunc/OnceValue/OnceValues may transitively keep more allocations alive. As the passed function is guaranteed to be called at most once, it is safe to drop it after the first call is complete. This avoids keeping the passed function (and anything it transitively references) alive until the returned function is GCed. Change-Id: I2faf397b481d2f693ab3aea8e2981b02adbc7a21 Reviewed-on: https://go-review.googlesource.com/c/go/+/481515 Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: qiulaidongfeng <2645477756@qq.com>
2023-11-20src: a/an grammar fixesVille Skyttä
Change-Id: I179b50ae8e73677d4d408b83424afbbfe6aa17a1 GitHub-Last-Rev: 2e2d9c1e45556155d02db4df381b99f2d1bc5c0e GitHub-Pull-Request: golang/go#63478 Reviewed-on: https://go-review.googlesource.com/c/go/+/534015 Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Dmitri Shuralyov <dmitshur@google.com> Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2023-11-17all: make more use of the new atomic integer typesDaniel Martí
Slightly simplifies the code and avoids human error. Change-Id: Ib76575e8bc5b3a699ba6cc3870d63cd7a55e6416 Reviewed-on: https://go-review.googlesource.com/c/go/+/541476 Reviewed-by: David Chase <drchase@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Bryan Mills <bcmills@google.com>
2023-10-06sync: use atomic.Uint32 in Oncemstmdev
Change-Id: If9089f8afd78de3e62cd575f642ff96ab69e2099 GitHub-Last-Rev: 14165018d67e84685dcf84be0320623ccb3afc0e GitHub-Pull-Request: golang/go#63386 Reviewed-on: https://go-review.googlesource.com/c/go/+/532895 Auto-Submit: Ian Lance Taylor <iant@google.com> Reviewed-by: Jorropo <jorropo.pgm@gmail.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Michael Pratt <mpratt@google.com> Auto-Submit: Michael Pratt <mpratt@google.com>
2023-09-07sync: deemphasize goroutines in RWMutex documentationqiulaidongfeng
Fixes #41555 Change-Id: I46b9535b1687d481d2ac76296e8ba7de26d6e2e2 Change-Id: I46b9535b1687d481d2ac76296e8ba7de26d6e2e2 GitHub-Last-Rev: 38af46c18922eea80e05c8ed9f5e10002ab7244d GitHub-Pull-Request: golang/go#61977 Reviewed-on: https://go-review.googlesource.com/c/go/+/518859 Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Cherry Mui <cherryyz@google.com> Run-TryBot: Bryan Mills <bcmills@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Bryan Mills <bcmills@google.com>
2023-09-01sync: prevent (*Map).Range from always escapingMauri de Souza Meneguzzo
After the change from CL 426074 the Range method on Map always escape the read variable, leading to an allocation. Since the compiler doesn't do live-range splitting for local variables we need to use some hints to only escape in that particular branch. Fixes #62404 Change-Id: I938a5e593647455fa827e3dd3ed8ea22c7365df1 GitHub-Last-Rev: fcbedb467c7b4e6f1d49e299d243cad70deb34e9 GitHub-Pull-Request: golang/go#62408 Reviewed-on: https://go-review.googlesource.com/c/go/+/524976 Auto-Submit: Bryan Mills <bcmills@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Run-TryBot: Bryan Mills <bcmills@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Reviewed-by: Bryan Mills <bcmills@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
2023-08-16sync: document why copyChecker checks the condition twiceqiulaidongfeng
Fixes #40924 Change-Id: I249a278be1ec3c67088819af4456e6c393431724 Change-Id: I249a278be1ec3c67088819af4456e6c393431724 GitHub-Last-Rev: 772c7ae7e140ebd3896fc7786aae8b43ab3128c3 GitHub-Pull-Request: golang/go#61978 Reviewed-on: https://go-review.googlesource.com/c/go/+/518961 Reviewed-by: David Chase <drchase@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com> Run-TryBot: Austin Clements <austin@google.com> Auto-Submit: Austin Clements <austin@google.com>
2023-07-31sync: panic rather than throw on nil *PoolIan Lance Taylor
Fixes #61651 Change-Id: I27d581719e6bf38910f9d47dcf023bbff74ddf72 Reviewed-on: https://go-review.googlesource.com/c/go/+/514037 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Ian Lance Taylor <iant@google.com> Auto-Submit: Ian Lance Taylor <iant@google.com> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Ian Lance Taylor <iant@google.com>