-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
time: NewTimer firing later if computer sleeps, how to use wall clock? #35012
Comments
This seems related to #24595 on GNU/Linux. Looking at the runtime package code I'm slightly surprised that this doesn't already work as you expect. I'm not sure how to fix it. |
Apparently there are two options: #24595 (comment) Maybe there should be two kinds of timer in Go, absolute and actual? cc @eliasnaur @zx2c4 |
A similar issue from last year 2018, that could use reading differences between the monotonic and wall clocks #29308 |
I patch Go using this patch for WireGuard: It's a network protocol, and phones and laptops like to sleep a lot these days, so this winds up being rather important. |
I found a lot of information about |
Yea for that patch above to be complete, I'll need to augment the semaphore code (and futex code on Linux), either doing the same trick as on Windows, or perhaps finding some special argument. On the linux front, I talked to tglx (kernel timer maintainer) a few weeks ago about making futex boottime aware, and so maybe we'll push that forward for future improvements, if nothing currently existing suffices. On the macOS front, I haven't researched yet. |
This is impossible if the computer is asleep during the time which
I find that allowing I believe the correct front-facing API solution to this potential problem is not to create a new timer, but to add a
That being written, I do not think this is a problem worth solving in the standard library due to its apparent implementation complexity. |
This is necessarily how the contract for timers/sleep/etc.. works. A program gets control some time after the delay you specified, ideally not too long afterwards. However, there are many reasons why a program may not get control "quickly":
The best we can hope for is that the OS/runtime doesn't unnecessarily delay providing control to the program. Programs need to be written to cope with this uncertainly otherwise they are likely buggy. In this case, I don't think we need a new timer, we just need the runtime to provide control as soon as is practical. At least, that allows the program to delay further if it is more appropriate. Afaict, having a timer that pauses during suspend is almost never what you want, and having a timer that fires as close to the intended wall clock duration is almost always what you want. If this is problematic, then the programs were likely buggy to begin with. |
I understand this, of course I don't mean that I expect the timer to fire if the computer is asleep. However something that has been happening to me is that I set a timer an hour from now, the computer sleeps for 15 mins within that hour (eg.) and the timer fires 1:15 hours later instead of 1 hour later. This is just a little counterintuitive. It's one thing if the host is asleep during the time when the timer is supposed to fire but the monotonic clock pausing is something that makes it almost impossible to schedule any work reliably. I think the default should be a non pausing monotonic clock (eg CLOCK_BOOTIME, which I hope is supported in macos?) since it's just more common sense behavior. |
If the process can sleep for |
It could, but that's seems less useful. Timers can be delayed for many reasons (see above). Programs should be able to cope with that where possible. However, if the timer fires unnecessarily late there is no opportunity to correct it and the experience is likely worse. Wall clock durations are well defined, and almost always what a programmer expects/assumes for timers. If a further delay is useful, it's easy enough to reschedule the timer. Otherwise, it's unclear what time a programmer might want, and how to define it. CPU time? Time the OS is available to schedule processes? Time the OS is available to schedule a particular process (eg, handle CPU contention, SIGSTOP)? These seem to be proxies for "work done", or "work potential" which could be measured other ways. The need for timers like this isn't particularly common in my experience. Consider a very common time event processing loop:
Using wall clock durations it will process events as close to the intended clock as is practical. Using "OS runtime durations" it will be further delayed after suspend, even if it could have been triggered on time.
There are few guarantees with timers and program scheduling (see reasons above). If there is a choice between "wall clock durations" and "OS runtime durations", I'd pick the one that's more useful. |
To be clear, I have no interest in implementing anything regarding the "wall clock". And I don't think @networkimprov's suggestions are viable. My future participation in this general category will consist of moving go from CLOCK_MONOTONIC to CLOCK_BOOTTIME, which will solve the original poster's problem as well as some others. |
As documented in the other thread, there are use cases for both kinds of timer (absolute and suspend-aware), and a lot of code that expects the current absolute kind. So the question should be whether to leave things as they are, or to add a suspend-aware timing API. @zx2c4 if it's viable to change the current scheme to clock_boottime, how could it be non-viable to add a timer API which uses that? |
@mpx What happens if the wall clock's time is changed? |
Disaster ensues. Hence my suggestion that we use CLOCK_BOOTTIME instead. |
Sorry, it seems there is a misunderstanding. It doesn't matter if the wall clock time is changed, timer durations are unaffected (that's what happens now, provided you don't suspend/resume). What I'm refering to is "real time passed" vs "time system running passed". So yes, |
Monotonic timers are paused during standby. Thus these timers won't fire after waking up. Fall back to periodic polling to detect too large clock jumps. See golang/go#35012 for a discussion of go timers during standby.
Monotonic timers are paused during standby. Thus these timers won't fire after waking up. Fall back to periodic polling to detect too large clock jumps. See golang/go#35012 for a discussion of go timers during standby.
Monotonic timers are paused during standby. Thus these timers won't fire after waking up. Fall back to periodic polling to detect too large clock jumps. See golang/go#35012 for a discussion of go timers during standby.
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
Yes
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
What did you expect to see?
This works until my macbook goes to sleep (macOS) I'm guessing that it's because of the monotonic clock stopping. Is there a way to create a Timer that fires using the wall clock?
I need the alarm to fire at the right time (after x amount of minutes/hours have passed) regardless of whether the computer went into sleep mode in between the time when the timer was created and when it was supposed to fire.
What did you see instead?
If macbook goes to sleep, timer clock stops and it fires way later than it was supposed to (depending on how long the computer slept)
The text was updated successfully, but these errors were encountered: