The Time.Sub function is mentioned in the previous sentence.
Change-Id: Ic79958cea4d1f9f9014f6dafd8e749c204db4f50
Reviewed-on: https://go-review.googlesource.com/c/go/+/606575
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
CL 586257 converted days to uint32 which is usually fine but fails for
negative days close to cycle boundaries.
Fixes#68718
Change-Id: I8dc5b8fe0c7c1921beb204da1913b9a1ab39280d
Reviewed-on: https://go-review.googlesource.com/c/go/+/602815
Reviewed-by: Rob Pike <r@golang.org>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Change-Id: Id0fb180a2d7910cdff7f4ab7154d9ceeb2f1cb71
GitHub-Last-Rev: 03658dd974
GitHub-Pull-Request: golang/go#68709
Reviewed-on: https://go-review.googlesource.com/c/go/+/602675
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
The current implementation fails to parse a time string with a "Z"
time zone using a time format that includes time zone seconds. This
fix correctly parses the "Z" time zone for any Z-base time format
that includes seconds (i.e. "Z070000" or "Z07:00:00").
Fixes#68263
Change-Id: Idf8fa06b5f96383f050c4ffbd2bc5804fd408650
Reviewed-on: https://go-review.googlesource.com/c/go/+/595897
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>
Reviewed-by: Than McIntosh <thanm@google.com>
The original implementation could not support a non-default metric,
but now that it is set during package time, we can. Do that.
Change-Id: If7929b0afa5b0142d299718d9bd811c5a8d1cf93
Reviewed-on: https://go-review.googlesource.com/c/go/+/589058
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Change-Id: I418953a766db22b134a9569161f06cf8682c1eef
Reviewed-on: https://go-review.googlesource.com/c/go/+/591336
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
When using time.RFC1123Z to parse the date header value out of an email,
an error is returned for dates that occur in the first 9 days of a
month. This is because the format strings for RFC 1123 defined in the
time package indicate that the day should be prefixed with a leading 0.
Reading the spec, the line that talks about it seems to indicate that
days can be either 1 or 2 digits:
`date = 1*2DIGIT month 2*4DIGIT`
So a date header with a day like `7` with no leading zero should be
accepted.
Fixes#67887
Change-Id: Ie7ee40d94da2c8c0417957e8b89f9987314949c8
GitHub-Last-Rev: 22a5a52fcb
GitHub-Pull-Request: golang/go#67888
Reviewed-on: https://go-review.googlesource.com/c/go/+/591335
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Change-Id: I5aaea4918f024a87146ba54a8d5307658d722fe9
Reviewed-on: https://go-review.googlesource.com/c/go/+/589635
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: hui zhou <hxzhouh@gmail.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Add linknames for most modules with ≥50 dependents.
Add linknames for a few other modules that we know
are important but are below 50.
Remove linknames from badlinkname.go that do not merit
inclusion (very small number of dependents).
We can add them back later if the need arises.
Fixes#67401. (For now.)
Change-Id: I1e49fec0292265256044d64b1841d366c4106002
Reviewed-on: https://go-review.googlesource.com/c/go/+/587756
Auto-Submit: Russ Cox <rsc@golang.org>
TryBot-Bypass: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Preparation for upcoming optimizations.
For #63844.
Change-Id: I61803dd8b699e51c391614c99ebbd005df5261cc
Reviewed-on: https://go-review.googlesource.com/c/go/+/586256
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Ignored these linknames which have not worked for a while:
github.com/xtls/xray-core:
context.newCancelCtx removed in CL 463999 (Feb 2023)
github.com/u-root/u-root:
funcPC removed in CL 513837 (Jul 2023)
tinygo.org/x/drivers:
net.useNetdev never existed
For #67401.
Change-Id: I9293f4ef197bb5552b431de8939fa94988a060ce
Reviewed-on: https://go-review.googlesource.com/c/go/+/587576
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Cherry Mui <cherryyz@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
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>
Fixes#67470
Change-Id: Idc5997859602ff6155aa9ae875b327fbcb53513d
Reviewed-on: https://go-review.googlesource.com/c/go/+/586717
Reviewed-by: Alan Donovan <adonovan@google.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>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
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>
As mentioned in CL 584598, linkname is a mechanism that, when
abused, can break API integrity and even safety of Go programs.
CL 584598 is a first step to restrict the use of linknames, by
implementing a blocklist. This CL takes a step further, tightening
up the restriction by allowing linkname references ("pull") only
when the definition side explicitly opts into it, by having a
linkname on the definition (possibly to itself). This way, it is at
least clear on the definition side that the symbol, despite being
unexported, is accessed outside of the package. Unexported symbols
without linkname can now be actually private. This is similar to
the symbol visibility rule used by gccgo for years (which defines
unexported non-linknamed symbols as C static symbols).
As there can be pull-only linknames in the wild that may be broken
by this change, we currently only enforce this rule for symbols
defined in the standard library. Push linknames are added in the
standard library to allow things build.
Linkname references to external (non-Go) symbols are still allowed,
as their visibility is controlled by the C symbol visibility rules
and enforced by the C (static or dynamic) linker.
Assembly symbols are treated similar to linknamed symbols.
This is controlled by -checklinkname linker flag, currently not
enabled by default. A follow-up CL will enable it by default.
Change-Id: I07344f5c7a02124dbbef0fbc8fec3b666a4b2b0e
Reviewed-on: https://go-review.googlesource.com/c/go/+/585358
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Russ Cox <rsc@golang.org>
Trying to write a test for the corner cases in the old async timer chan
implementation may have been a mistake, especially since this isn't
going to be the default timer chan implementation anymore.
But let's try one more time to fix the test.
I reproduced the remaining builder failures on my Mac laptop
by overloading the CPU in one window and then running 48 instances
of the flaky test in loops using 'stress' in another window.
It turns out that, contrary to my understanding of async timers
and therefore contrary to what the test expected, it is technically
possible for
t := time.NewTicker(1)
t.Reset(1000*time.Hour)
<-t.C
<-t.C
to observe two time values on t.C, as opposed to blocking forever.
We always expect the first time value, since the ticker goes off
immediately (after 1ns) and sends that value into the channel buffer.
To get the second value, the ticker has to be in the process of
going off (which it is doing constantly anyway), and the timer
goroutine has to be about to call sendTime and then get rescheduled.
Then t.Reset and the first <-t.C have to happen.
Then the timer goroutine gets rescheduled and can run sendTime's
non-blocking send on t.C, which finds an empty buffer and writes
a value.
This is unlikely, of course, but it definitely happens. This program
always panics in just a second or two on my laptop:
package main
import (
"os"
"time"
)
func main() {
os.Setenv("GODEBUG", "asynctimerchan=1")
for {
go func() {
t := time.NewTicker(1)
t.Reset(1000*time.Hour)
<-t.C
select {
case <-t.C:
panic("two receives")
case <-time.After(1*time.Second):
}
}()
}
}
Because I did not understand this nuance, the test did not expect it.
This CL rewrites the test to expect that possibility. I can no longer
make the test fail under 'stress' on my laptop.
For #66322.
Change-Id: I15c75d2c6f24197c43094da20d6ab55306a0a9f1
Reviewed-on: https://go-review.googlesource.com/c/go/+/585359
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Russ Cox <rsc@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Change-Id: I82f0e7c0c0c80a3cc0e4a732a59ae1debb37d8d9
GitHub-Last-Rev: c8a081f5b3
GitHub-Pull-Request: golang/go#67166
Reviewed-on: https://go-review.googlesource.com/c/go/+/583195
Commit-Queue: Ian Lance Taylor <iant@google.com>
Reviewed-by: Keith Randall <khr@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Keith Randall <khr@golang.org>
Auto-Submit: Keith Randall <khr@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
See #66870
Change-Id: I781265355a3dbd0d9538bc9dcafaa83b482ec3f8
GitHub-Last-Rev: 9d92f116b0
GitHub-Pull-Request: golang/go#66922
Reviewed-on: https://go-review.googlesource.com/c/go/+/580515
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Joedian Reid <joedian@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
The overall time package tests increase from 3.85s to 4.85s on my laptop.
But they should be less flaky, and the time is spent sleeping, so it won't
slow down the overall machine running multiple package tests in
parallel.
For #66322.
Change-Id: I66d6647c389c943b53045e8836ede4ba3d4670c7
Reviewed-on: https://go-review.googlesource.com/c/go/+/581315
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Change-Id: Idfe9cf2f2e4750d6673455f98deef2efc2d292a6
Reviewed-on: https://go-review.googlesource.com/c/go/+/539837
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Ian Lance Taylor <iant@golang.org>
A proposal discussion in mid-2020 on #37196 decided to change
time.Timer and time.Ticker so that their Stop and Reset methods
guarantee that no old value (corresponding to the previous configuration
of the Timer or Ticker) will be received after the method returns.
The trivial way to do this is to make the Timer/Ticker channels
unbuffered, create a goroutine per Timer/Ticker feeding the channel,
and then coordinate with that goroutine during Stop/Reset.
Since Stop/Reset coordinate with the goroutine and the channel
is unbuffered, there is no possibility of a stale value being sent
after Stop/Reset returns.
Of course, we do not want an extra goroutine per Timer/Ticker,
but that's still a good semantic model: behave like the channels
are unbuffered and fed by a coordinating goroutine.
The actual implementation is more effort but behaves like the model.
Specifically, the timer channel has a 1-element buffer like it always has,
but len(t.C) and cap(t.C) are special-cased to return 0 anyway, so user
code cannot see what's in the buffer except with a receive.
Stop/Reset lock out any stale sends and then clear any pending send
from the buffer.
Some programs will change behavior. For example:
package main
import "time"
func main() {
t := time.NewTimer(2 * time.Second)
time.Sleep(3 * time.Second)
if t.Reset(2*time.Second) != false {
panic("expected timer to have fired")
}
<-t.C
<-t.C
}
This program (from #11513) sleeps 3s after setting a 2s timer,
resets the timer, and expects Reset to return false: the Reset is too
late and the send has already occurred. It then expects to receive
two values: the one from before the Reset, and the one from after
the Reset.
With an unbuffered timer channel, it should be clear that no value
can be sent during the time.Sleep, so the time.Reset returns true,
indicating that the Reset stopped the timer from going off.
Then there is only one value to receive from t.C: the one from after the Reset.
In 2015, I used the above example as an argument against this change.
Note that a correct version of the program would be:
func main() {
t := time.NewTimer(2 * time.Second)
time.Sleep(3 * time.Second)
if !t.Reset(2*time.Second) {
<-t.C
}
<-t.C
}
This works with either semantics, by heeding t.Reset's result.
The change should not affect correct programs.
However, one way that the change would be visible is when programs
use len(t.C) (instead of a non-blocking receive) to poll whether the timer
has triggered already. We might legitimately worry about breaking such
programs.
In 2020, discussing #37196, Bryan Mills and I surveyed programs using
len on timer channels. These are exceedingly rare to start with; nearly all
the uses are buggy; and all the buggy programs would be fixed by the new
semantics. The details are at [1].
To further reduce the impact of this change, this CL adds a temporary
GODEBUG setting, which we didn't know about yet in 2015 and 2020.
Specifically, asynctimerchan=1 disables the change and is the default
for main programs in modules that use a Go version before 1.23.
We hope to be able to retire this setting after the minimum 2-year window.
Setting asynctimerchan=1 also disables the garbage collection change
from CL 568341, although users shouldn't need to know that since
it is not a semantically visible change (unless we have bugs!).
As an undocumented bonus that we do not officially support,
asynctimerchan=2 disables the channel buffer change but keeps
the garbage collection change. This may help while we are
shaking out bugs in either of them.
Fixes#37196.
[1] https://github.com/golang/go/issues/37196#issuecomment-641698749
Change-Id: I8925d3fb2b86b2ae87fd2acd055011cbf7bd5916
Reviewed-on: https://go-review.googlesource.com/c/go/+/568341
Reviewed-by: Austin Clements <austin@google.com>
Auto-Submit: Russ Cox <rsc@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Change-Id: I56ca2d11637d60c6b0656fdc1d900a2384aba141
GitHub-Last-Rev: 686e02db77
GitHub-Pull-Request: golang/go#66264
Reviewed-on: https://go-review.googlesource.com/c/go/+/570916
Reviewed-by: qiulaidongfeng <2645477756@qq.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Classic operating system kernel mistake: if you start using
per-CPU data without disabling interrupts on the CPU,
and then an interrupt reschedules the process onto a different
CPU, now you're using the wrong CPU's per-CPU data.
The same thing happens in Go if you use per-M or per-P
data structures while not holding a lock nor using acquirem.
In the original timer.modify before CL 564977, I had been
very careful about this during the "unlock t; lock ts" dance,
only calling releasem after ts was locked. That made sure
we used the right ts. The refactoring of that code into its
own helper function in CL 564977 missed that nuance.
The code
ts := &getg().m.p.p.ptr().timers
ts.lock()
was now executing without holding any locks nor acquirem.
If the goroutine changed its M or P between deciding which
ts to use and actually locking that ts, the code would proceed
to add the timer t to some other P's timers. If the P was idle
by then, the scheduler could have already checked it for timers
and not notice the newly added timer when deciding when the
next timer should trigger.
The solution is to do what the old code correctly did, namely
acquirem before deciding which ts to use, rather than assume
getg().m.p won't change before ts.lock can complete.
This CL does that.
Before CL 564977,
stress ./time.test -test.run='ZeroTimer/impl=(func|cache)' -test.timeout=3m -test.count=20
ran without failure for over an hour on my laptop.
Starting in CL 564977, it consistently failed within a few minutes.
After this CL, it now runs without failure for over an hour again.
Fixes#66006.
Change-Id: Ib9e7ccaa0f22a326ce3fdef2b9a92f7f0bdafcbf
Reviewed-on: https://go-review.googlesource.com/c/go/+/571196
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
From the beginning of Go, the time package has had a gotcha:
if you use a select on <-time.After(1*time.Minute), even if the select
finishes immediately because some other case is ready, the underlying
timer from time.After keeps running until the minute is over. This
pins the timer in the timer heap, which keeps it from being garbage
collected and in extreme cases also slows down timer operations.
The lack of garbage collection is the more important problem.
The docs for After warn against this scenario and suggest using
NewTimer with a call to Stop after the select instead, purely to work
around this garbage collection problem.
Oddly, the docs for NewTimer and NewTicker do not mention this
problem, but they have the same issue: they cannot be collected until
either they are Stopped or, in the case of Timer, the timer expires.
(Tickers repeat, so they never expire.) People have built up a shared
knowledge that timers and tickers need to defer t.Stop even though the
docs do not mention this (it is somewhat implied by the After docs).
This CL fixes the garbage collection problem, so that a timer that is
unreferenced can be GC'ed immediately, even if it is still running.
The approach is to only insert the timer into the heap when some
channel operation is blocked on it; the last channel operation to stop
using the timer takes it back out of the heap. When a timer's channel
is no longer referenced, there are no channel operations blocked on
it, so it's not in the heap, so it can be GC'ed immediately.
This CL adds an undocumented GODEBUG asynctimerchan=1
that will disable the change. The documentation happens in
the CL 568341.
Fixes#8898.
Fixes#61542.
Change-Id: Ieb303b6de1fb3527d3256135151a9e983f3c27e6
Reviewed-on: https://go-review.googlesource.com/c/go/+/512355
Reviewed-by: Austin Clements <austin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Russ Cox <rsc@golang.org>
Comparing BenchmarkStop against very old commits like
CL 13094043, I was very confused about how timers had
gotten almost 10X slower since 2013.
It turns out that CL 68060043 introduced a factor of 1000
in the benchmark cost, by counting batches of 1000 as 1 op
instead of 1000 ops, and timers have actually gotten
dramatically faster since 2013, with the addition of per-P
timer heaps and other optimizations.
This CL rewrites the benchmarks to use testing.PB directly,
so that the factor of 1000 disappears, and "/op" really means "/op".
In the few tests that need to run in batches for one reason or
another, add "1000" to the name to make clear that batches
are being run.
Change-Id: I27ed74d1e420934982e4205aad4f218cdfc42509
Reviewed-on: https://go-review.googlesource.com/c/go/+/570495
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
The timers had evolved to the point where the state was stored as follows:
if timer in heap:
state has timerHeaped set
if heap timer is stale:
heap deadline in t.when
real deadline in t.nextWhen
state has timerNextWhen set
else:
real deadline in t.when
t.nextWhen unset
else:
real deadline in t.when
t.nextWhen unset
That made it hard to find the real deadline and just hard to think about everything.
The new state is:
real deadline in t.when (always)
if timer in heap:
state has timerHeaped set
heap deadline in t.whenHeap
if heap timer is stale:
state has timerModified set
Separately, the 'state' word itself was being used as a lock
and state bits because the code started with CAS loops,
which we abstracted into the lock/unlock methods step by step.
At this point, we can switch to a real lock, making sure to
publish the one boolean needed by timers fast paths
at each unlock.
All this simplifies various logic considerably.
Change-Id: I35766204f7a26d999206bd56cc0db60ad1b17cbe
Reviewed-on: https://go-review.googlesource.com/c/go/+/570335
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Austin Clements <austin@google.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>
Change-Id: I1dbd1c5aa26f458cdac7a3f0ca974254a069311f
GitHub-Last-Rev: da481ba7a9
GitHub-Pull-Request: golang/go#66219
Reviewed-on: https://go-review.googlesource.com/c/go/+/569897
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
The simulators are too slow.
Change-Id: I0aaf2304ad0881c74886ff3185c09614de2aae63
Reviewed-on: https://go-review.googlesource.com/c/go/+/570236
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Russ Cox <rsc@golang.org>
If user code has two timers t1 and t2 and does *t1 = *t2
(or *t1 = Timer{}), it creeps me out that we would be
corrupting the runtime data structures inlined in the
Timer struct. Replace that field with a pointer to the
runtime data structure instead, so that the corruption
cannot happen, even in a badly behaved program.
In fact, remove the struct definition entirely and linkname
a constructor instead. Now the runtime can evolve the struct
however it likes without needing to keep package time in sync.
Also move the workaround logic for #21874 out of
runtime and into package time.
Change-Id: Ia30f7802ee7b3a11f5d8a78dd30fd9c8633dc787
Reviewed-on: https://go-review.googlesource.com/c/go/+/568339
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Many of the tests in package time are about proper manipulation
of the timer heap. But now NewTimer bypasses the timer heap
except when something is blocked on the associated channel.
Make the tests test the heap again by using AfterFunc instead of
NewTimer.
In particular, adds a non-chan version of TestZeroTimer, which
was flaky-broken and then fixed by CLs in the cleanup stack.
This new tests makes sure we notice if it breaks again.
Fixes#66006.
Change-Id: Ib59fc1b8b85ef5a21e72fe418c627c9b8b8a083a
Reviewed-on: https://go-review.googlesource.com/c/go/+/568255
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Russ Cox <rsc@golang.org>
Reviewed-by: Austin Clements <austin@google.com>
The current implementation sets t.ts before adding t to ts;
that can cause inconsistencies with temporarily negative
ts.zombies values. Handle them gracefully, since we only
care about detecting very positive values.
Pending CL 564977 removes the race that sets t.ts early,
and then CL 569996 builds on top of that to make the count precise.
This CL just gets examples like the new test working sooner.
Change-Id: Ibe1aecc2554f83436f761f48e4050bd962982e4f
Reviewed-on: https://go-review.googlesource.com/c/go/+/569995
Reviewed-by: Austin Clements <austin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Continuing conversion from C to Go, introduce type timers
encapsulating all timer heap state, with methods for operations.
This should at least be easier to think about, instead of having
these fields strewn through the P struct. It should also be easier
to test.
I am skeptical about the pair of atomic int64 deadlines:
I think there are missed wakeups lurking.
Having the code in an abstracted API should make it easier
to reason through and fix if needed.
[This is one CL in a refactoring stack making very small changes
in each step, so that any subtle bugs that we miss can be more
easily pinpointed to a small change.]
Change-Id: If5ea3e0b946ca14076f44c85cbb4feb9eddb4f95
Reviewed-on: https://go-review.googlesource.com/c/go/+/564132
Reviewed-by: Austin Clements <austin@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Russ Cox <rsc@golang.org>
modtimer can always be used in place of addtimer.
Do that and delete addtimer, avoiding duplicated logic.
[This is one CL in a refactoring stack making very small changes
in each step, so that any subtle bugs that we miss can be more
easily pinpointed to a small change.]
Change-Id: I70291796bdac3bef5e0850f039f6f4a1da4498ae
Reviewed-on: https://go-review.googlesource.com/c/go/+/564118
Reviewed-by: Ian Lance Taylor <iant@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
When readying a goroutine, the scheduler typically places the readied
goroutine in pp.runnext, which will typically be the next goroutine to
run in the schedule.
In order to prevent a set of ping-pong goroutines from simply switching
back and forth via runnext and starving the rest of the run queue, a
goroutine scheduled via runnext shares a time slice (pp.schedtick) with
the previous goroutine.
sysmon detects "long-running goroutines", which really means Ps using
the same pp.schedtick for too long, and preempts them to allow the rest
of the run queue to run. Thus this avoids starvation via runnext.
However, wasm has no threads, and thus no sysmon. Without sysmon to
preempt, the possibility for starvation returns. Avoid this by disabling
runnext entirely on wasm. This means that readied goroutines always go
on the end of the run queue and thus cannot starve via runnext.
Note that this CL doesn't do anything about single long-running
goroutines. Without sysmon to preempt them, a single goroutine that
fails to yield will starve the run queue indefinitely.
For #65178.
Change-Id: I10859d088776125a2af8c9cd862b6e071da628b5
Cq-Include-Trybots: luci.golang.try:gotip-js-wasm,gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero
Reviewed-on: https://go-review.googlesource.com/c/go/+/559798
Auto-Submit: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Change-Id: I0d42bca7c6ee63c05a0ca09c165f2f591edf7c34
Reviewed-on: https://go-review.googlesource.com/c/go/+/565356
Auto-Submit: Ian Lance Taylor <iant@google.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: Tobias Klauser <tobias.klauser@gmail.com>
GetQueuedCompletionStatusEx has a ~16ms timeout resolution. Use a
WaitCompletionPacket associated with the I/O Completion Port (IOCP)
and a high resolution timer so the IOCP is signaled on timer expiry,
therefore improving the GetQueuedCompletionStatusEx timeout resolution.
BenchmarkSleep from the time package shows an important improvement:
goos: windows
goarch: amd64
pkg: time
cpu: Intel(R) Core(TM) i7-10850H CPU @ 2.70GHz
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
Sleep-12 1258.5µ ± 5% 250.7µ ± 1% -80.08% (p=0.000 n=20)
Fixes#44343.
Change-Id: I79fc09e34dddfc49e0e23c3d1d0603926c22a11d
Reviewed-on: https://go-review.googlesource.com/c/go/+/488675
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Quim Muntal <quimmuntal@gmail.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Bryan Mills <bcmills@google.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
A typo without consequences, but confusing nonetheless. The last
line prints micro2 and then micro, instead of micro2 twice.
One-character fix.
Fixes#65666
Change-Id: I61d636382a2223d53eac58d6ddbcc7c15b4efc85
Reviewed-on: https://go-review.googlesource.com/c/go/+/563275
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Run-TryBot: Rob Pike <r@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Change-Id: I13ed84b99459d5844abb6e932cc4b8e0bd3ae9f5
Reviewed-on: https://go-review.googlesource.com/c/go/+/561215
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>
Reviewed-by: David Chase <drchase@google.com>
This reverts CL 557437.
Reason for revert: Appears to have broken wasip1 builders.
For #65178.
Change-Id: I59c1a310eb56589c768536fe444c1efaf862f8b0
Reviewed-on: https://go-review.googlesource.com/c/go/+/559237
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Pratt <mpratt@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
When readying a goroutine, the scheduler typically places the readied
goroutine in pp.runnext, which will typically be the next goroutine to
run in the schedule.
In order to prevent a set of ping-pong goroutines from simply switching
back and forth via runnext and starving the rest of the run queue, a
goroutine scheduled via runnext shares a time slice (pp.schedtick) with
the previous goroutine.
sysmon detects "long-running goroutines", which really means Ps using
the same pp.schedtick for too long, and preempts them to allow the rest
of the run queue to run. Thus this avoids starvation via runnext.
However, wasm has no threads, and thus no sysmon. Without sysmon to
preempt, the possibility for starvation returns. Avoid this by disabling
runnext entirely on wasm. This means that readied goroutines always go
on the end of the run queue and thus cannot starve via runnext.
Note that this CL doesn't do anything about single long-running
goroutines. Without sysmon to preempt them, a single goroutine that
fails to yield will starve the run queue indefinitely.
For #65178.
Cq-Include-Trybots: luci.golang.try:gotip-js-wasm,gotip-wasip1-wasm_wasmtime,gotip-wasip1-wasm_wazero
Change-Id: I7dffe1e72c6586474186b72f8068cff77b661eae
Reviewed-on: https://go-review.googlesource.com/c/go/+/557437
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Mauri de Souza Meneguzzo <mauri870@gmail.com>
Reviewed-by: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
The test is skipped on wasm platforms for now, because it
successfully detects a starvation bug on those platforms.
For #65178.
Change-Id: I05d28f1c7be99fcab67ec4dfaa38f412e11fd3cb
Reviewed-on: https://go-review.googlesource.com/c/go/+/557038
Auto-Submit: Bryan Mills <bcmills@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
Change-Id: Iba8878420c59d705066d1d9955e91a5c2eb4faf5
Reviewed-on: https://go-review.googlesource.com/c/go/+/507615
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
Auto-Submit: Ian Lance Taylor <iant@google.com>
The additional empty line was inadvertently introduced by CL 526676,
causing only part of the Time godoc to be rendered on pkg.go.dev.
Change-Id: I868315752eb160ebaab227c8b5369054c557cb7e
Reviewed-on: https://go-review.googlesource.com/c/go/+/531877
Reviewed-by: Ian Lance Taylor <iant@google.com>
Reviewed-by: Dmitri Shuralyov <dmitshur@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Dmitri Shuralyov <dmitshur@google.com>