Skip to content
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: time.After() seems to return early by 5 milliseconds sometimes. #17294

Closed
DavidVorick opened this issue Sep 30, 2016 · 7 comments

Comments

Projects
None yet
5 participants
@DavidVorick
Copy link

commented Sep 30, 2016

Please answer these questions before submitting your issue. Thanks!

What version of Go are you using (go version)?

go version go1.7.1 linux/amd64

What operating system and processor architecture are you using (go env)?

amd64
linux

Qubes -> Whonix (Debian based)

What did you do?

https://play.golang.org/p/YLOXGJrc92

What did you expect to see?

Locked the trylock
Lock failed, time passed: 500ms

What did you see instead?

Locked the trylock
Lock failed, time passed: 495ms


I've only been able to reproduce this on my machine, but time.After was returning 5 milliseconds early in a few contexts with similar code. Not a big deal for my project, but wanted to report that I was seeing unexpected things.

@DavidVorick

This comment has been minimized.

Copy link
Author

commented Sep 30, 2016

go test -timeout=500s is sometimes returning after only 497 seconds. So it seems to be a similar problem. Are there two different timers being used? Perhaps hardware vs. software clocks? Maybe my machine is not synchronized with itself.

@bradfitz

This comment has been minimized.

Copy link
Member

commented Sep 30, 2016

Yes, one is monotonic time and one is wall time.

Does this only happen in Qubes for you, which I believe is running your process under Xen?

@DavidVorick

This comment has been minimized.

Copy link
Author

commented Sep 30, 2016

I've only seen it so far on Qubes, which indeed uses Xen. I also had several AppVMs running at once, which means that they were being switched out. I'm guessing that's the source of the discrepency.

@quentinmit

This comment has been minimized.

Copy link
Contributor

commented Sep 30, 2016

5ms out of 500ms is a 1% error. I would be shocked if monotonic and wall time were that different over a half a second.

Do you have ntpd running in your VM? Or are you using Xen's clock syncing? What is the output of cat /sys/devices/system/clocksource/clocksource0/current_clocksource ?

@quentinmit quentinmit added this to the Go1.8 milestone Sep 30, 2016

@DavidVorick

This comment has been minimized.

Copy link
Author

commented Sep 30, 2016

looks like xen is running as the clock source.

output is xen

@rsc

This comment has been minimized.

Copy link
Contributor

commented Oct 18, 2016

This was caused by 86c976f which was done for #6007: the 500ms sleep is monotonic clock ms, and the measured 495ms is wall time ms.

The fact is that if your monotonic and wall clocks don't line up, you're going to be in for trouble one way or another. It used to be one way. Now it's another. I wish we hadn't changed it, but not enough to change it back.

@rsc rsc closed this Oct 18, 2016

@rsc

This comment has been minimized.

Copy link
Contributor

commented Feb 4, 2017

FWIW, I expect this program to work as expected now if built with Go's master branch, after the fix for #12914 that landed today. Both the time.After and the time.Now().Sub(start) shold be using the same clock, and they should both report 500ms. If you were to subtract t.UnixNano() or something like that, you'd still see 495ms, but I expect that is an accurate reflection of xen turning your clock back.

@golang golang locked and limited conversation to collaborators Feb 4, 2018

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.