aboutsummaryrefslogtreecommitdiff
path: root/src/runtime/chan.go
AgeCommit message (Collapse)Author
2021-02-23cmd/compile,runtime: make selectnbrecv return two valuesCuong Manh Le
The only different between selectnbrecv and selectnbrecv2 is the later set the input pointer value by second return value from chanrecv. So by making selectnbrecv return two values from chanrecv, we can get rid of selectnbrecv2, the compiler can now call only selectnbrecv and generate simpler code. Change-Id: Ifaf6cf1314c4f47b06ed9606b1578319be808507 Reviewed-on: https://go-review.googlesource.com/c/go/+/292890 Trust: Cuong Manh Le <cuong.manhle.vn@gmail.com> Run-TryBot: Cuong Manh Le <cuong.manhle.vn@gmail.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2020-11-25runtime: check channel's elemsize before calling race detectorDaniel S Fava
When c.elemsize==0 we call raceacquire() and racerelease() as opposed to calling racereleaseacquire() The reason for this change is that, when elemsize==0, we don't allocate a full buffer for the channel. Instead of individual buffer entries, the race detector uses the c.buf as the only buffer entry. This simplification prevents us following the memory model's happens-before rules implemented in racereleaseacquire(). So, instead of calling racereleaseacquire(), we accumulate happens-before information in the synchronization object associated with c.buf. The functionality in this change is implemented in a new function called racenotify() Fixes #42598 Change-Id: I75b92708633fdfde658dc52e06264e2171824e51 Reviewed-on: https://go-review.googlesource.com/c/go/+/271987 Reviewed-by: Dmitry Vyukov <dvyukov@google.com> Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Dmitry Vyukov <dvyukov@google.com> TryBot-Result: Go Bot <gobot@golang.org> Trust: Ian Lance Taylor <iant@golang.org>
2020-11-13runtime: swap the order of raceacquire() and racerelease()Daniel S Fava
In chansend() and chanrecv() of chan.go, the order of calls to raceacquire() and racerelease() was swapped, which meant that the code was not following the memory model "by the letter of the law." Similar for bufrecv and bufsend in select.go The memory model says: - A send happens before the corresponding receive completes, and - the kth receive on a channel with capacity C happens before the k+C send on that channel completes. The operative word here is "completes." For example, a sender obtains happens-before information on completion of the send-operation, which means, after the sender has deposited its message onto the channel. Similarly for receives. If the order of raceacquire() and racerelease() is incorrect, the race detector may fail to report some race conditions. The fix is minimal from the point of view of Go. The fix does, however, rely on a new function added to TSan: https://reviews.llvm.org/D76322 This commit only affects execution when race detection is enabled. Added two tests into `runtime/race/output_test.go`: - `chanmm` tests for the issue addressed by this patch - `mutex` is a test for inverted semaphores, which must not be broken by this (or any other) patch Fixes #37355 Change-Id: I5e886879ead2bd456a4b7dd1d17253641b767f63 Reviewed-on: https://go-review.googlesource.com/c/go/+/220419 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Go Bot <gobot@golang.org> Trust: Dmitri Shuralyov <dmitshur@golang.org> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
2020-09-21runtime: disable stack shrinking in activeStackChans race windowMichael Anthony Knyszek
Currently activeStackChans is set before a goroutine blocks on a channel operation in an unlockf passed to gopark. The trouble is that the unlockf is called *after* the G's status is changed, and the G's status is what is used by a concurrent mark worker (calling suspendG) to determine that a G has successfully been suspended. In this window between the status change and unlockf, the mark worker could try to shrink the G's stack, and in particular observe that activeStackChans is false. This observation will cause the mark worker to *not* synchronize with concurrent channel operations when it should, and so updating pointers in the sudog for the blocked goroutine (which may point to the goroutine's stack) races with channel operations which may also manipulate the pointer (read it, dereference it, update it, etc.). Fix the problem by adding a new atomically-updated flag to the g struct called parkingOnChan, which is non-zero in the race window above. Then, in isShrinkStackSafe, check if parkingOnChan is zero. The race is resolved like so: * Blocking G sets parkingOnChan, then changes status in gopark. * Mark worker successfully suspends blocking G. * If the mark worker observes parkingOnChan is non-zero when checking isShrinkStackSafe, then it's not safe to shrink (we're in the race window). * If the mark worker observes parkingOnChan as zero, then because the mark worker observed the G status change, it can be sure that gopark's unlockf completed, and gp.activeStackChans will be correct. The risk of this change is low, since although it reduces the number of places that stack shrinking is allowed, the window here is incredibly small. Essentially, every place that it might crash now is replaced with no shrink. This change adds a test, but the race window is so small that it's hard to trigger without a well-placed sleep in park_m. Also, this change fixes stackGrowRecursive in proc_test.go to actually allocate a 128-byte stack frame. It turns out the compiler was destructuring the "pad" field and only allocating one uint64 on the stack. Fixes #40641. Change-Id: I7dfbe7d460f6972b8956116b137bc13bc24464e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/247050 Run-TryBot: Michael Knyszek <mknyszek@google.com> TryBot-Result: Go Bot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> Trust: Michael Knyszek <mknyszek@google.com>
2020-08-18runtime: add "success" field to sudogMatthew Dempsky
The current wakeup protocol for channel communications is that the second goroutine sets gp.param to the sudog when a value is successfully communicated over the channel, and to nil when the wakeup is due to closing the channel. Setting nil to indicate channel closure works okay for chansend and chanrecv, because they're only communicating with one channel, so they know it must be the channel that was closed. However, it means selectgo has to re-poll all of the channels to figure out which one was closed. This commit adds a "success" field to sudog, and changes the wakeup protocol to always set gp.param to sg, and to use sg.success to indicate successful communication vs channel closure. While here, this also reorganizes the chansend code slightly so that the sudog is still released to the pool if the send blocks and then is awoken because the channel closed. Updates #40410. Change-Id: I6cd9a20ebf9febe370a15af1b8afe24c5539efc6 Reviewed-on: https://go-review.googlesource.com/c/go/+/245019 Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Cuong Manh Le <cuong.manhle.vn@gmail.com> Reviewed-by: Keith Randall <khr@golang.org>
2020-04-07runtime: static lock ranking for the runtime (enabled by GOEXPERIMENT)Dan Scales
I took some of the infrastructure from Austin's lock logging CR https://go-review.googlesource.com/c/go/+/192704 (with deadlock detection from the logs), and developed a setup to give static lock ranking for runtime locks. Static lock ranking establishes a documented total ordering among locks, and then reports an error if the total order is violated. This can happen if a deadlock happens (by acquiring a sequence of locks in different orders), or if just one side of a possible deadlock happens. Lock ordering deadlocks cannot happen as long as the lock ordering is followed. Along the way, I found a deadlock involving the new timer code, which Ian fixed via https://go-review.googlesource.com/c/go/+/207348, as well as two other potential deadlocks. See the constants at the top of runtime/lockrank.go to show the static lock ranking that I ended up with, along with some comments. This is great documentation of the current intended lock ordering when acquiring multiple locks in the runtime. I also added an array lockPartialOrder[] which shows and enforces the current partial ordering among locks (which is embedded within the total ordering). This is more specific about the dependencies among locks. I don't try to check the ranking within a lock class with multiple locks that can be acquired at the same time (i.e. check the ranking when multiple hchan locks are acquired). Currently, I am doing a lockInit() call to set the lock rank of most locks. Any lock that is not otherwise initialized is assumed to be a leaf lock (a very high rank lock), so that eliminates the need to do anything for a bunch of locks (including all architecture-dependent locks). For two locks, root.lock and notifyList.lock (only in the runtime/sema.go file), it is not as easy to do lock initialization, so instead, I am passing the lock rank with the lock calls. For Windows compilation, I needed to increase the StackGuard size from 896 to 928 because of the new lock-rank checking functions. Checking of the static lock ranking is enabled by setting GOEXPERIMENT=staticlockranking before doing a run. To make sure that the static lock ranking code has no overhead in memory or CPU when not enabled by GOEXPERIMENT, I changed 'go build/install' so that it defines a build tag (with the same name) whenever any experiment has been baked into the toolchain (by checking Expstring()). This allows me to avoid increasing the size of the 'mutex' type when static lock ranking is not enabled. Fixes #38029 Change-Id: I154217ff307c47051f8dae9c2a03b53081acd83a Reviewed-on: https://go-review.googlesource.com/c/go/+/207619 Reviewed-by: Dan Scales <danscales@google.com> Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Dan Scales <danscales@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2020-03-22runtime: speed up receive on empty closed channelBen Schwartz
Currently, nonblocking receive on an open channel is about 700 times faster than nonblocking receive on a closed channel. This change makes closed channels equally fast. Fixes #32529. Includes a correction based on #36714. relevant benchstat output: name old time/op new time/op delta MakeChan/Byte-40 140ns ± 4% 137ns ± 7% -2.38% (p=0.023 n=17+19) MakeChan/Int-40 174ns ± 5% 173ns ± 6% ~ (p=0.437 n=18+19) MakeChan/Ptr-40 315ns ±15% 301ns ±15% ~ (p=0.051 n=20+20) MakeChan/Struct/0-40 123ns ± 8% 99ns ±11% -19.18% (p=0.000 n=20+17) MakeChan/Struct/32-40 297ns ± 8% 241ns ±18% -19.13% (p=0.000 n=20+20) MakeChan/Struct/40-40 344ns ± 5% 273ns ±23% -20.49% (p=0.000 n=20+20) ChanNonblocking-40 0.32ns ± 2% 0.32ns ± 2% -1.25% (p=0.000 n=19+18) SelectUncontended-40 5.72ns ± 1% 5.71ns ± 2% ~ (p=0.326 n=19+19) SelectSyncContended-40 10.9µs ±10% 10.6µs ± 3% -2.77% (p=0.009 n=20+16) SelectAsyncContended-40 1.00µs ± 0% 1.10µs ± 0% +10.75% (p=0.000 n=18+19) SelectNonblock-40 1.22ns ± 2% 1.21ns ± 4% ~ (p=0.141 n=18+19) ChanUncontended-40 240ns ± 4% 233ns ± 4% -2.82% (p=0.000 n=20+20) ChanContended-40 86.7µs ± 0% 82.7µs ± 0% -4.64% (p=0.000 n=20+19) ChanSync-40 294ns ± 7% 284ns ± 9% -3.44% (p=0.006 n=20+20) ChanSyncWork-40 38.4µs ±19% 34.0µs ± 4% -11.33% (p=0.000 n=20+18) ChanProdCons0-40 1.50µs ± 1% 1.63µs ± 0% +8.53% (p=0.000 n=19+19) ChanProdCons10-40 1.17µs ± 0% 1.18µs ± 1% +0.44% (p=0.000 n=19+20) ChanProdCons100-40 985ns ± 0% 959ns ± 1% -2.64% (p=0.000 n=20+20) ChanProdConsWork0-40 1.50µs ± 0% 1.60µs ± 2% +6.54% (p=0.000 n=18+20) ChanProdConsWork10-40 1.26µs ± 0% 1.26µs ± 2% +0.40% (p=0.015 n=20+19) ChanProdConsWork100-40 1.27µs ± 0% 1.22µs ± 0% -4.15% (p=0.000 n=20+19) SelectProdCons-40 1.50µs ± 1% 1.53µs ± 1% +1.95% (p=0.000 n=20+20) ChanCreation-40 82.1ns ± 5% 81.6ns ± 7% ~ (p=0.483 n=19+19) ChanSem-40 877ns ± 0% 719ns ± 0% -17.98% (p=0.000 n=18+19) ChanPopular-40 1.75ms ± 2% 1.78ms ± 3% +1.76% (p=0.002 n=20+19) ChanClosed-40 215ns ± 1% 0ns ± 6% -99.82% (p=0.000 n=20+18) Previously committed in CL 181543 and reverted in CL 216158. Change-Id: Ib767b08d724cfad03598d77271dbc1087485feb8 Reviewed-on: https://go-review.googlesource.com/c/go/+/216818 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2020-01-24Revert "runtime: speed up receive on empty closed channel"Alexander Rakoczy
This reverts CL 181543 (git e1446d9cee91af263af15efe8291644b590bb9ff) Reason for revert: Caused a regression in the race detector. Updates #32529 Fixes #36714 Change-Id: Ifefe6784f86ea72f414a89f131c239e9c9fd74eb Reviewed-on: https://go-review.googlesource.com/c/go/+/216158 Run-TryBot: Alexander Rakoczy <alex@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Emmanuel Odeke <emm.odeke@gmail.com> Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2019-10-25runtime: make copystack/sudog synchronization more explicitAustin Clements
When we copy a stack of a goroutine blocked in a channel operation, we have to be very careful because other goroutines may be writing to that goroutine's stack. To handle this, stack copying acquires the locks for the channels a goroutine is waiting on. One complication is that stack growth may happen while a goroutine holds these locks, in which case stack copying must *not* acquire these locks because that would self-deadlock. Currently, stack growth never acquires these locks because stack growth only happens when a goroutine is running, which means it's either not blocking on a channel or it's holding the channel locks already. Stack shrinking always acquires these locks because shrinking happens asynchronously, so the goroutine is never running, so there are either no locks or they've been released by the goroutine. However, we're about to change when stack shrinking can happen, which is going to break the current rules. Rather than find a new way to derive whether to acquire these locks or not, this CL simply adds a flag to the g struct that indicates that stack copying should acquire channel locks. This flag is set while the goroutine is blocked on a channel op. For #10958, #24543. Change-Id: Ia2ac8831b1bfda98d39bb30285e144c4f7eaf9ab Reviewed-on: https://go-review.googlesource.com/c/go/+/172982 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Knyszek <mknyszek@google.com>
2019-10-07runtime: speed up receive on empty closed channelBen Schwartz
Currently, nonblocking receive on an open channel is about 700 times faster than nonblocking receive on a closed channel. This change makes closed channels equally fast. Fixes #32529 relevant benchstat output: name old time/op new time/op delta MakeChan/Byte-40 140ns ± 4% 137ns ± 7% -2.38% (p=0.023 n=17+19) MakeChan/Int-40 174ns ± 5% 173ns ± 6% ~ (p=0.437 n=18+19) MakeChan/Ptr-40 315ns ±15% 301ns ±15% ~ (p=0.051 n=20+20) MakeChan/Struct/0-40 123ns ± 8% 99ns ±11% -19.18% (p=0.000 n=20+17) MakeChan/Struct/32-40 297ns ± 8% 241ns ±18% -19.13% (p=0.000 n=20+20) MakeChan/Struct/40-40 344ns ± 5% 273ns ±23% -20.49% (p=0.000 n=20+20) ChanNonblocking-40 0.32ns ± 2% 0.32ns ± 2% -1.25% (p=0.000 n=19+18) SelectUncontended-40 5.72ns ± 1% 5.71ns ± 2% ~ (p=0.326 n=19+19) SelectSyncContended-40 10.9µs ±10% 10.6µs ± 3% -2.77% (p=0.009 n=20+16) SelectAsyncContended-40 1.00µs ± 0% 1.10µs ± 0% +10.75% (p=0.000 n=18+19) SelectNonblock-40 1.22ns ± 2% 1.21ns ± 4% ~ (p=0.141 n=18+19) ChanUncontended-40 240ns ± 4% 233ns ± 4% -2.82% (p=0.000 n=20+20) ChanContended-40 86.7µs ± 0% 82.7µs ± 0% -4.64% (p=0.000 n=20+19) ChanSync-40 294ns ± 7% 284ns ± 9% -3.44% (p=0.006 n=20+20) ChanSyncWork-40 38.4µs ±19% 34.0µs ± 4% -11.33% (p=0.000 n=20+18) ChanProdCons0-40 1.50µs ± 1% 1.63µs ± 0% +8.53% (p=0.000 n=19+19) ChanProdCons10-40 1.17µs ± 0% 1.18µs ± 1% +0.44% (p=0.000 n=19+20) ChanProdCons100-40 985ns ± 0% 959ns ± 1% -2.64% (p=0.000 n=20+20) ChanProdConsWork0-40 1.50µs ± 0% 1.60µs ± 2% +6.54% (p=0.000 n=18+20) ChanProdConsWork10-40 1.26µs ± 0% 1.26µs ± 2% +0.40% (p=0.015 n=20+19) ChanProdConsWork100-40 1.27µs ± 0% 1.22µs ± 0% -4.15% (p=0.000 n=20+19) SelectProdCons-40 1.50µs ± 1% 1.53µs ± 1% +1.95% (p=0.000 n=20+20) ChanCreation-40 82.1ns ± 5% 81.6ns ± 7% ~ (p=0.483 n=19+19) ChanSem-40 877ns ± 0% 719ns ± 0% -17.98% (p=0.000 n=18+19) ChanPopular-40 1.75ms ± 2% 1.78ms ± 3% +1.76% (p=0.002 n=20+19) ChanClosed-40 215ns ± 1% 0ns ± 6% -99.82% (p=0.000 n=20+18) Change-Id: I6d5ca4f1530cc9e1a9f3ef553bbda3504a036448 Reviewed-on: https://go-review.googlesource.com/c/go/+/181543 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2019-09-03cmd/compile,runtime: generate hash functions only for types which are map keysKeith Randall
Right now we generate hash functions for all types, just in case they are used as map keys. That's a lot of wasted effort and binary size for types which will never be used as a map key. Instead, generate hash functions only for types that we know are map keys. Just doing that is a bit too simple, since maps with an interface type as a key might have to hash any concrete key type that implements that interface. So for that case, implement hashing of such types at runtime (instead of with generated code). It will be slower, but only for maps with interface types as keys, and maybe only a bit slower as the aeshash time probably dominates the dispatch time. Reorg where we keep the equals and hash functions. Move the hash function from the key type to the map type, saving a field in every non-map type. That leaves only one function in the alg structure, so get rid of that and just keep the equal function in the type descriptor itself. cmd/go now has 10 generated hash functions, instead of 504. Makes cmd/go 1.0% smaller. Update #6853. Speed on non-interface keys is unchanged. Speed on interface keys is ~20% slower: name old time/op new time/op delta MapInterfaceString-8 23.0ns ±21% 27.6ns ±14% +20.01% (p=0.002 n=10+10) MapInterfacePtr-8 19.4ns ±16% 23.7ns ± 7% +22.48% (p=0.000 n=10+8) Change-Id: I7c2e42292a46b5d4e288aaec4029bdbb01089263 Reviewed-on: https://go-review.googlesource.com/c/go/+/191198 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Martin Möhrmann <moehrmann@google.com>
2019-03-27sort, internal/reflectlite: flesh out reflectlite enough for use by sortBrad Fitzpatrick
Now the net package is back to no longer depending on unicode. And lock that in with a test. Fixes #30440 Change-Id: I18b89b02f7d96488783adc07308da990f505affd Reviewed-on: https://go-review.googlesource.com/c/go/+/169137 Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
2019-03-25runtime: remove kindNoPointersKeith Randall
We already have the ptrdata field in a type, which encodes exactly the same information that kindNoPointers does. My problem with kindNoPointers is that it often leads to double-negative code like: t.kind & kindNoPointers != 0 Much clearer is: t.ptrdata == 0 Update #27167 Change-Id: I92307d7f018a6bbe3daca4a4abb4225e359349b1 Reviewed-on: https://go-review.googlesource.com/c/go/+/169157 Run-TryBot: Keith Randall <khr@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
2019-03-05all: join a few chained ifsDaniel Martí
I had been finding these over a year or so, but none were big enough changes to warrant CLs. They're a handful now, so clean them all up in a single commit. The smaller bodies get a bit simpler, but most importantly, the larger bodies get unindented. Change-Id: I5707a6fee27d4c9ff9efd3d363af575d7a4bf2aa Reviewed-on: https://go-review.googlesource.com/c/go/+/165340 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2018-10-23runtime: use multiplication with overflow check for makechanMartin Möhrmann
This improves performance for channels with an element size larger than 32 bytes and removes loading a value from the maxElems array for smaller element sizes. MakeChan/Byte 88.8ns ± 6% 85.2ns ± 1% -4.03% (p=0.000 n=10+10) MakeChan/Int 100ns ± 4% 96ns ± 2% -3.72% (p=0.000 n=9+10) MakeChan/Ptr 124ns ± 3% 126ns ± 2% ~ (p=0.068 n=10+10) MakeChan/Struct/0 80.5ns ± 2% 80.7ns ± 2% ~ (p=0.697 n=10+10) MakeChan/Struct/32 143ns ± 4% 141ns ± 2% ~ (p=0.221 n=10+10) MakeChan/Struct/40 169ns ± 2% 159ns ± 4% -6.26% (p=0.000 n=10+10) Updates #21588 Change-Id: Ifbf12a5af2f0ec7e1d2241ecfffab020e9abec48 Reviewed-on: https://go-review.googlesource.com/c/144017 Reviewed-by: Keith Randall <khr@golang.org>
2018-10-03cmd/compile,runtime: remove ambiguously live logicKeith Randall
The previous CL introduced stack objects. This CL removes the old ambiguously live liveness analysis. After this CL we're relying on stack objects exclusively. Update a bunch of liveness tests to reflect the new world. Fixes #22350 Change-Id: I739b26e015882231011ce6bc1a7f426049e59f31 Reviewed-on: https://go-review.googlesource.com/c/134156 Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Cherry Zhang <cherryyz@google.com>
2018-09-18runtime: ignore races between close and len/capKeith Randall
They aren't really races, or at least they don't have any observable effect. The spec is silent on whether these are actually races or not. Fix this problem by not using the address of len (or of cap) as the location where channel operations are recorded to occur. Use a random other field of hchan for that. I'm not 100% sure we should in fact fix this. Opinions welcome. Fixes #27070 Change-Id: Ib4efd4b62e0d1ef32fa51e373035ef207a655084 Reviewed-on: https://go-review.googlesource.com/135698 Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
2018-08-20runtime: use gList in closechanAustin Clements
Change-Id: I8148eb17fe9f2cbb659c35d84cdd212b46dc23bf Reviewed-on: https://go-review.googlesource.com/129401 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
2018-05-03runtime: convert g.waitreason from string to uint8Josh Bleecher Snyder
Every time I poke at #14921, the g.waitreason string pointer writes show up. They're not particularly important performance-wise, but it'd be nice to clear the noise away. And it does open up a few extra bytes in the g struct for some future use. This is a re-roll of CL 99078, which was rolled back because of failures on s390x. Those failures were apparently due to an old version of gdb. Change-Id: Icc2c12f449b2934063fd61e272e06237625ed589 Reviewed-on: https://go-review.googlesource.com/111256 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Michael Munday <mike.munday@ibm.com>
2018-03-13Revert "runtime: convert g.waitreason from string to uint8"Josh Bleecher Snyder
This reverts commit 4eea887fd477368653f6fcf8ad766030167936e5. Reason for revert: broke s390x build Change-Id: Id6c2b6a7319273c4d21f613d4cdd38b00d49f847 Reviewed-on: https://go-review.googlesource.com/100375 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
2018-03-12runtime: convert g.waitreason from string to uint8Josh Bleecher Snyder
Every time I poke at #14921, the g.waitreason string pointer writes show up. They're not particularly important performance-wise, but it'd be nice to clear the noise away. And it does open up a few extra bytes in the g struct for some future use. Change-Id: I7ffbd52fbc2a286931a2218038fda52ed6473cc9 Reviewed-on: https://go-review.googlesource.com/99078 Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Austin Clements <austin@google.com>
2018-02-15runtime: replace _MaxMem with maxAllocAustin Clements
Now that we have memLimit, also having _MaxMem is a bit confusing. Replace it with maxAlloc, which better conveys what it limits. We also define maxAlloc slightly differently: since it's now clear that it limits allocation size, we can account for a subtle difference between 32-bit and 64-bit. Change-Id: Iac39048018cc0dae7f0919e25185fee4b3eed529 Reviewed-on: https://go-review.googlesource.com/85890 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
2018-02-13runtime: eliminate all writebarrierptr* callsAustin Clements
Calls to writebarrierptr can simply be actual pointer writes. Calls to writebarrierptr_prewrite need to go through the write barrier buffer. Updates #22460. Change-Id: I92cee4da98c5baa499f1977563757c76f95bf0ca Reviewed-on: https://go-review.googlesource.com/92704 Run-TryBot: Austin Clements <austin@google.com> Reviewed-by: Rick Hudson <rlh@golang.org>
2017-09-22runtime: remove getcallerpc argumentAustin Clements
Now that getcallerpc is a compiler intrinsic on x86 and non-x86 platforms don't need the argument, we can drop it. Sadly, this doesn't let us remove any dummy arguments since all of those cases also use getcallersp, which still takes the argument pointer, but this is at least an improvement. Change-Id: I9c34a41cf2c18cba57f59938390bf9491efb22d2 Reviewed-on: https://go-review.googlesource.com/65474 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: David Chase <drchase@google.com>
2017-08-17runtime: improve makechan memory checks and allocation callsMartin Möhrmann
Use mallogc instead of newarray to save some overhead since makechan already checks for _MaxMem constraints. Flattens the if else construct that determines if buf and hchan struct should be allocated in one mallocgc call and where buf should point to. Uses maxSliceCap to avoid divisions similar to makeslice. name old time/op new time/op delta MakeChan/Byte 82.0ns ± 8% 81.4ns ± 7% ~ (p=0.643 n=10+10) MakeChan/Int 97.9ns ± 2% 96.6ns ± 2% -1.40% (p=0.009 n=10+10) MakeChan/Ptr 128ns ± 3% 120ns ± 1% -6.63% (p=0.000 n=10+10) MakeChan/Struct/0 66.7ns ± 4% 66.4ns ± 2% ~ (p=0.697 n=10+10) MakeChan/Struct/32 136ns ± 1% 130ns ± 0% -4.42% (p=0.000 n=10+10) MakeChan/Struct/40 150ns ± 1% 150ns ± 1% ~ (p=0.725 n=10+10) Change-Id: Ibb5675d0843a072aae2bfa58ecd39cf4cd926533 Reviewed-on: https://go-review.googlesource.com/55132 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2017-08-15runtime: move selectdone into gDaniel Morsing
Writing to selectdone on the stack of another goroutine meant a pretty subtle dance between the select code and the stack copying code. Instead move the selectdone variable into the g struct. Change-Id: Id246aaf18077c625adef7ca2d62794afef1bdd1b Reviewed-on: https://go-review.googlesource.com/53390 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2017-08-15cmd/compile: generate makechan calls with int argumentsMartin Möhrmann
Where possible generate calls to runtime makechan with int arguments during compile time instead of makechan with int64 arguments. This eliminates converting arguments for calls to makechan with int64 arguments for platforms where int64 values do not fit into arguments of type int. A similar optimization for makeslice was introduced in CL golang.org/cl/27851. 386: name old time/op new time/op delta MakeChan/Byte 52.4ns ± 6% 45.0ns ± 1% -14.14% (p=0.000 n=10+10) MakeChan/Int 54.5ns ± 1% 49.1ns ± 1% -9.87% (p=0.000 n=10+10) MakeChan/Ptr 150ns ± 1% 143ns ± 0% -4.38% (p=0.000 n=9+7) MakeChan/Struct/0 49.2ns ± 2% 43.2ns ± 2% -12.27% (p=0.000 n=10+10) MakeChan/Struct/32 81.7ns ± 2% 76.2ns ± 1% -6.71% (p=0.000 n=10+10) MakeChan/Struct/40 88.4ns ± 2% 82.5ns ± 2% -6.60% (p=0.000 n=10+10) AMD64: name old time/op new time/op delta MakeChan/Byte 83.4ns ± 8% 80.8ns ± 3% ~ (p=0.171 n=10+10) MakeChan/Int 101ns ± 3% 101ns ± 2% ~ (p=0.412 n=10+10) MakeChan/Ptr 128ns ± 1% 128ns ± 1% ~ (p=0.191 n=10+10) MakeChan/Struct/0 67.6ns ± 3% 68.7ns ± 4% ~ (p=0.224 n=10+10) MakeChan/Struct/32 138ns ± 1% 139ns ± 1% ~ (p=0.185 n=10+9) MakeChan/Struct/40 154ns ± 1% 154ns ± 1% -0.55% (p=0.027 n=10+9) Change-Id: Ie854cb066007232c5e9f71ea7d6fe27e81a9c050 Reviewed-on: https://go-review.googlesource.com/55140 Run-TryBot: Martin Möhrmann <moehrmann@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2017-03-21runtime: remove unused *chantype parametersDaniel Martí
The chanrecv funcs don't use it at all. The chansend ones do, but the element type is now part of the hchan struct, which is already a parameter. hchan can be nil in chansend when sending to a nil channel, so when instrumenting we must copy to the stack to be able to read the channel type. name old time/op new time/op delta ChanUncontended 6.42µs ± 1% 6.22µs ± 0% -3.06% (p=0.000 n=19+18) Initially found by github.com/mvdan/unparam. Fixes #19591. Change-Id: I3a5e8a0082e8445cc3f0074695e3593fd9c88412 Reviewed-on: https://go-review.googlesource.com/38351 Run-TryBot: Daniel Martí <mvdan@mvdan.cc> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2017-03-07runtime: join selectgo and selectgoImplAustin Clements
Currently selectgo is just a wrapper around selectgoImpl. This keeps the hard-coded frame skip counts for tracing the same between the channel implementation and the select implementation. However, this is fragile and confusing, so pass a skip parameter to send and recv, join selectgo and selectgoImpl into one function, and use decrease all of the skips in selectgo by one. Change-Id: I11b8cbb7d805b55f5dc6ab4875ac7dde79412ff2 Reviewed-on: https://go-review.googlesource.com/37860 Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Matthew Dempsky <mdempsky@google.com>
2016-10-31runtime: perform write barriers on direct channel receiveAustin Clements
Currently we have write barriers for direct channel sends, where the receiver is blocked and the sender is writing directly to the receiver's stack; but not for direct channel receives, where the sender is blocked and the receiver is reading directly from the sender's stack. This was okay with the old write barrier because either 1) the receiver would write the received pointer into the heap (causing it to be shaded), 2) the pointer would still be on the receiver's stack at mark termination and we would rescan it, or 3) the receiver dropped the pointer so it wasn't necessarily reachable anyway. This is not okay with the write barrier because it lets a grey stack send a white pointer to a black stack and then remove it from its own stack. If the grey stack was the sole grey-protector of this pointer, this hides the object from the garbage collector. Fix this by making direct receives perform a stack-to-stack write barrier just like direct sends do. Fixes #17694. Change-Id: I1a4cb904e4138d2ac22f96a3e986635534a5ae41 Reviewed-on: https://go-review.googlesource.com/32450 Reviewed-by: Rick Hudson <rlh@golang.org>
2016-10-28runtime: perform write barrier before pointer writeAustin Clements
Currently, we perform write barriers after performing pointer writes. At the moment, it simply doesn't matter what order this happens in, as long as they appear atomic to GC. But both the hybrid barrier and ROC are going to require a pre-write write barrier. For the hybrid barrier, this is important because the barrier needs to observe both the current value of the slot and the value that will be written to it. (Alternatively, the caller could do the write and pass in the old value, but it seems easier and more useful to just swap the order of the barrier and the write.) For ROC, this is necessary because, if the pointer write is going to make the pointer reachable to some goroutine that it currently is not visible to, the garbage collector must take some special action before that pointer becomes more broadly visible. This commits swaps pointer writes around so the write barrier occurs before the pointer write. The main subtlety here is bulk memory writes. Currently, these copy to the destination first and then use the pointer bitmap of the destination to find the copied pointers and invoke the write barrier. This is necessary because the source may not have a pointer bitmap. To handle these, we pass both the source and the destination to the bulk memory barrier, which uses the pointer bitmap of the destination, but reads the pointer values from the source. Updates #17503. Change-Id: I78ecc0c5c94ee81c29019c305b3d232069294a55 Reviewed-on: https://go-review.googlesource.com/31763 Reviewed-by: Rick Hudson <rlh@golang.org>
2016-10-28runtime: use typedmemclr for typed memoryAustin Clements
The hybrid barrier requires distinguishing typed and untyped memory even when zeroing because the *current* contents of the memory matters even when overwriting. This commit introduces runtime.typedmemclr and runtime.memclrHasPointers as a typed memory clearing functions parallel to runtime.typedmemmove. Currently these simply call memclr, but with the hybrid barrier we'll need to shade any pointers we're overwriting. These will provide us with the necessary hooks to do so. Updates #17503. Change-Id: I74478619f8907825898092aaa204d6e4690f27e6 Reviewed-on: https://go-review.googlesource.com/31366 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Rick Hudson <rlh@golang.org>
2016-10-24runtime: fix invariant comment in chan.goRuss Cox
Change-Id: Ic6317f186d0ee68ab1f2d15be9a966a152f61bfb Reviewed-on: https://go-review.googlesource.com/31610 Run-TryBot: Russ Cox <rsc@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Keith Randall <khr@golang.org>
2016-04-21runtime: use type int to specify size for newarrayMartin Möhrmann
Consistently use type int for the size argument of runtime.newarray, runtime.reflect_unsafe_NewArray and reflect.unsafe_NewArray. Change-Id: Ic77bf2dde216c92ca8c49462f8eedc0385b6314e Reviewed-on: https://go-review.googlesource.com/22311 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Martin Möhrmann <martisch@uos.de> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-04-20runtime: simplify mallocgc flag argumentKeith Randall
mallocgc can calculate noscan itself. The only remaining flag argument is needzero, so we just make that a boolean arg. Fixes #15379 Change-Id: I839a70790b2a0c9dbcee2600052bfbd6c8148e20 Reviewed-on: https://go-review.googlesource.com/22290 Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com> Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-04-10runtime: make execution error panic values implement the Error interfaceEmmanuel Odeke
Make execution panics implement Error as mandated by https://golang.org/ref/spec#Run_time_panics, instead of panics with strings. Fixes #14965 Change-Id: I7827f898b9b9c08af541db922cc24fa0800ff18a Reviewed-on: https://go-review.googlesource.com/21214 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-16runtime: define lock order between G status and channel lockAustin Clements
Currently, locking a G's stack by setting its status to _Gcopystack or _Gscan is unordered with respect to channel locks. However, when we make stack shrinking concurrent, stack shrinking will need to lock the G and then acquire channel locks, which imposes an order on these. Document this lock ordering and fix closechan to respect it. Everything else already happens to respect it. For #12967. Change-Id: I4dd02675efffb3e7daa5285cf75bf24f987d90d4 Reviewed-on: https://go-review.googlesource.com/20041 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-16runtime: protect sudog.elem with hchan.lockAustin Clements
Currently sudog.elem is never accessed concurrently, so in several cases we drop the channel lock just before reading/writing the sent/received value from/to sudog.elem. However, concurrent stack shrinking is going to have to adjust sudog.elem to point to the new stack, which means it needs a way to synchronize with accesses to sudog.elem. Hence, add sudog.elem to the fields protected by hchan.lock and scoot the unlocks down past the uses of sudog.elem. While we're here, better document the channel synchronization rules. For #12967. Change-Id: I3ad0ca71f0a74b0716c261aef21b2f7f13f74917 Reviewed-on: https://go-review.googlesource.com/20040 Reviewed-by: Keith Randall <khr@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-16runtime: record channel in sudogAustin Clements
Given a G, there's currently no way to find the channel it's blocking on. We'll need this information to fix a (probably theoretical) bug in select and to implement concurrent stack shrinking, so record the channel in the sudog. For #12967. Change-Id: If8fb63a140f1d07175818824d08c0ebeec2bdf66 Reviewed-on: https://go-review.googlesource.com/20035 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-07runtime: eliminate unnecessary type conversionsMatthew Dempsky
Automated refactoring produced using github.com/mdempsky/unconvert. Change-Id: Iacf871a4f221ef17f48999a464ab2858b2bbaa90 Reviewed-on: https://go-review.googlesource.com/20071 Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Matthew Dempsky <mdempsky@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-03-02all: single space after period.Brad Fitzpatrick
The tree's pretty inconsistent about single space vs double space after a period in documentation. Make it consistently a single space, per earlier decisions. This means contributors won't be confused by misleading precedence. This CL doesn't use go/doc to parse. It only addresses // comments. It was generated with: $ perl -i -npe 's,^(\s*// .+[a-z]\.) +([A-Z]),$1 $2,' $(git grep -l -E '^\s*//(.+\.) +([A-Z])') $ go test go/doc -update Change-Id: Iccdb99c37c797ef1f804a94b22ba5ee4b500c4f7 Reviewed-on: https://go-review.googlesource.com/20022 Reviewed-by: Rob Pike <r@golang.org> Reviewed-by: Dave Day <djd@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-02-25runtime: document non-obvious requirement on sudog.elemAustin Clements
The channel code must not allow stack splits between when it assigns a potential stack pointer to sudog.elem (or sudog.selectdone) and when it makes the sudog visible to copystack by putting it on the g.waiting list. We do get this right everywhere, but add a comment about this subtlety for future eyes. Change-Id: I941da150437167acff37b0e56983c793f40fcf79 Reviewed-on: https://go-review.googlesource.com/19632 Reviewed-by: Rick Hudson <rlh@golang.org> Run-TryBot: Austin Clements <austin@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org>
2016-02-23all: fix typosShawn Smith
Change-Id: I6035941df8b0de6aeaf6c05df7257bcf6e9191fe Reviewed-on: https://go-review.googlesource.com/19320 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
2015-11-10runtime: break atomics out into package runtime/internal/atomicMichael Matloob
This change breaks out most of the atomics functions in the runtime into package runtime/internal/atomic. It adds some basic support in the toolchain for runtime packages, and also modifies linux/arm atomics to remove the dependency on the runtime's mutex. The mutexes have been replaced with spinlocks. all trybots are happy! In addition to the trybots, I've tested on the darwin/arm64 builder, on the darwin/arm builder, and on a ppc64le machine. Change-Id: I6698c8e3cf3834f55ce5824059f44d00dc8e3c2f Reviewed-on: https://go-review.googlesource.com/14204 Run-TryBot: Michael Matloob <matloob@golang.org> Reviewed-by: Russ Cox <rsc@golang.org>
2015-11-08runtime: simplify chan ops, take 2Keith Randall
This change is the same as CL #9345 which was reverted, except for a small bug fix. The only change is to the body of sendDirect and its callsite. Also added a test. The problem was during a channel send operation. The target of the send was a sleeping goroutine waiting to receive. We basically do: 1) Read the destination pointer out of the sudog structure 2) Copy the value we're sending to that destination pointer Unfortunately, the previous change had a goroutine suspend point between 1 & 2 (the call to sendDirect). At that point the destination goroutine's stack could be copied (shrunk). The pointer we read in step 1 is no longer valid for step 2. Fixed by not allowing any suspension points between 1 & 2. I suspect the old code worked correctly basically by accident. Fixes #13169 The original 9345: This change removes the retry mechanism we use for buffered channels. Instead, any sender waking up a receiver or vice versa completes the full protocol with its counterpart. This means the counterpart does not need to relock the channel when it wakes up. (Currently buffered channels need to relock on wakeup.) For sends on a channel with waiting receivers, this change replaces two copies (sender->queue, queue->receiver) with one (sender->receiver). For receives on channels with a waiting sender, two copies are still required. This change unifies to a large degree the algorithm for buffered and unbuffered channels, simplifying the overall implementation. Fixes #11506 Change-Id: I57dfa3fc219cffa4d48301ee15fe5479299efa09 Reviewed-on: https://go-review.googlesource.com/16740 Reviewed-by: Ian Lance Taylor <iant@golang.org>
2015-11-06Revert "runtime: simplify buffered channels."Keith Randall
Revert for now until #13169 is understood. This reverts commit 8e496f1d6923172291658f0a785bdb47cc152325. Change-Id: Ib3eb2588824ef47a2b6eb9e377a24e5c817fcc81 Reviewed-on: https://go-review.googlesource.com/16716 Reviewed-by: Keith Randall <khr@golang.org>
2015-11-05runtime: simplify buffered channels.Keith Randall
This change removes the retry mechanism we use for buffered channels. Instead, any sender waking up a receiver or vice versa completes the full protocol with its counterpart. This means the counterpart does not need to relock the channel when it wakes up. (Currently buffered channels need to relock on wakeup.) For sends on a channel with waiting receivers, this change replaces two copies (sender->queue, queue->receiver) with one (sender->receiver). For receives on channels with a waiting sender, two copies are still required. This change unifies to a large degree the algorithm for buffered and unbuffered channels, simplifying the overall implementation. Fixes #11506 benchmark old ns/op new ns/op delta BenchmarkChanProdCons10 125 110 -12.00% BenchmarkChanProdCons0 303 284 -6.27% BenchmarkChanProdCons100 75.5 71.3 -5.56% BenchmarkChanContended 6452 6125 -5.07% BenchmarkChanNonblocking 11.5 11.0 -4.35% BenchmarkChanCreation 149 143 -4.03% BenchmarkChanSem 63.6 61.6 -3.14% BenchmarkChanUncontended 6390 6212 -2.79% BenchmarkChanSync 282 276 -2.13% BenchmarkChanProdConsWork10 516 506 -1.94% BenchmarkChanProdConsWork0 696 685 -1.58% BenchmarkChanProdConsWork100 470 469 -0.21% BenchmarkChanPopular 660427 660012 -0.06% Change-Id: I164113a56432fbc7cace0786e49c5a6e6a708ea4 Reviewed-on: https://go-review.googlesource.com/9345 Run-TryBot: Keith Randall <khr@golang.org> Reviewed-by: Austin Clements <austin@google.com> Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
2015-10-21runtime, syscall: add calls to msan functionsIan Lance Taylor
Add explicit memory sanitizer instrumentation to the runtime and syscall packages. The compiler does not instrument the runtime package. It does instrument the syscall package, but we need to add a couple of cases that it can't see. Change-Id: I2d66073f713fe67e33a6720460d2bb8f72f31394 Reviewed-on: https://go-review.googlesource.com/16164 Reviewed-by: David Crawshaw <crawshaw@golang.org>
2015-07-13runtime: add memory barrier for sync send in selectRuss Cox
Missed select case when adding the barrier last time. All the more reason to refactor this code in Go 1.6. Fixes #11643. Change-Id: Ib0d19d6e0939296c0a3e06dda5e9b76f813bbc7e Reviewed-on: https://go-review.googlesource.com/12086 Reviewed-by: Austin Clements <austin@google.com>
2015-06-15runtime: use type-based write barrier for remote stack write during chansendRuss Cox
A send on an unbuffered channel to a blocked receiver is the only case in the runtime where one goroutine writes directly to the stack of another. The garbage collector assumes that if a goroutine is blocked, its stack contains no new pointers since the last time it ran. The send on an unbuffered channel violates this, so it needs an explicit write barrier. It has an explicit write barrier, but not one that can handle a write to another stack. Use one that can (based on type bitmap instead of heap bitmap). To make this work, raise the limit for type bitmaps so that they are used for all types up to 64 kB in size (256 bytes of bitmap). (The runtime already imposes a limit of 64 kB for a channel element size.) I have been unable to reproduce this problem in a simple test program. Could help #11035. Change-Id: I06ad994032d8cff3438c9b3eaa8d853915128af5 Reviewed-on: https://go-review.googlesource.com/10815 Reviewed-by: Austin Clements <austin@google.com>