Posts: 643
Threads: 120
Joined: Aug 2006
My system time synced yesterday and the time jumped forward 4seconds.
This dinged my driver which uses Time.GetCurStamp() to calculate CommPort.ReadByte(, WaitFor) times.
If I modify my code to use GetCurMillis  to calculate WaitFor (careful not to get bitten by wrap-around).  Will I be immune to system time changes?
Thanks -- Bob
P.S.  I supposed it is possible that CommPort.ReadByte *itself* will not WaitFor the correct amount of time if there is a system time change, so maybe I'm wasting my time trying to fix this.  I have increased the frequency of time synchronization so hopefully less of a probably anyway...
Posts: 40,483
Threads: 491
Joined: Aug 2002
GetCurMillis uses whatever the OS feature is that provides current millis. Given that the name of the underlying OS call is GetTickCount(), presumably it's just counting some sort of CPU or chip set timer ticks, but weirder things have happened.
Using the time stamp is a lot more efficient and simpler if you are waiting in a loop for something and processing other messages as you wait, since you calculate one end time and that's that, and just use it on each read call. If you use MS in that case, you have to recalculate each time and handle rounding and such. But obviously you can do it.
The only time it would really bite you is if you are waiting for a response. For polling type stuff, you just either wouldn't get it this time and would get it next time, or you'd wait some seconds longer than expected maybe if it went the other way.
There is apparently a WM_TIMECHANGE msg that gets sent. I could monitor for it in a background thread that is already monitoring such things for other types of changes. But, it doesn't tell you anything other than the time was changed. It doesn't saw how far, whether it was forward or back or what. So it would be sort of hard to make practical use of in something like this. It could be checked for I guess and the end time just recalculated again and you wait again for the original length of time. Or I guess you could calculate how much time you've used each time and then recalculate from the new current time plus that maybe.
But it would be silly to do that everywhere such things happen. It would have to be wrapped in some some sort of way and everyone call the same thing.
But, anyhoo, presumably the millis are tick driven.
Dean Roddey
Explorans limites defectum
Posts: 40,483
Threads: 491
Joined: Aug 2002
BTW, GetTickCount is a 32 bit value and will wrap around every 49.7 days of continuous system up time. There is a 64 bit version of it that I should probably add support for, which would solve that, though the current one would have to remain for backwards compatibility. You could of course always check for the new value to be less than the last one you saw and calculate the wrap around.
Dealing with time is never simple in the computer.
Dean Roddey
Explorans limites defectum
Posts: 643
Threads: 120
Joined: Aug 2006
Okay, thanks! I think GetTickCount should be safe for me.
I rewrote my time calcs and we'll see if the problem goes away for good.
--Bob
P.S. This is kind of a weird situation where I am inferring the state of the device based on the lack of a packet (which normally arrives at 1 second interval). I should think most drivers wouldn't mind if a few seconds appear or disappear now and then...
Posts: 643
Threads: 120
Joined: Aug 2006
Okay, after my code modifications, I'm still getting timeouts when the system clock changes.  However, the next poll picked up a packet and my packet time calculation (based on previous packet arrival with GetCurMillis), it says the packet actually arrived on time!  I strongly suspect ReadByte is not waiting for WaitFor millis when there is a system clock change.
Can you take a quick look at your CommPort ReadByte and ReadBuffer implementations and see if they are likely to wait the correct amount of time if there is a system time change?  If you are just passing through to some windows function can you tell me the name?  Very curious indeed.
Thanks -- Bob
P.S.  I can probably just modify my ReadByte calls to retry if it returns False, but there is still time on the GetCurMillis clock...  Ugh.
P.P.S.  I found the Windows10 registry entry which supposedly controls the time sync interval:
Computer\HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\W32Time\TimeProviders\NtpClient\SpecialPollInterval
It was set to 86,400secs = 24hrs.  I modified it to 21,600secs = 6hrs (but I haven't rebooted).  For some reason my system resyncs every 26hrs (93,600secs).  Weird.
Posts: 40,483
Threads: 491
Joined: Aug 2002
12-09-2018, 02:45 PM
(This post was last modified: 12-09-2018, 02:47 PM by Dean Roddey.)
Yeh, that's true. To avoid code duplication, the MS one just calculates the end time and calls the other version, because there's quite a bit of code involved for such a simple thing. In fact ALL of the socket stuff that comes in two variations does that, and that would be a huge change to deal with because there's a lot of code involved. And even worse since they do because the underlying virtual kernel layer methods that they in turn call all take the end time scheme.
As it stands, I'm not sure there's a good way around it. Well, you could put your own GetCurMillis64() calls around the read so that you know for sure how long it actually was. Call it before the read and after and subtract for millis actually waited.
What I don't get is how your system clock could be off so much in a 24 hour period. It shouldn't drift a large amount, right? I guess device drivers can override the tick interrupt and slow it down or something. Maybe lower it to once an hour so that the adjustment is very small and not likely to ever be an issue?
Some folks I saw were saying that the Java runtime does something (or it has in the past) to mess up the Windows clock.
Dean Roddey
Explorans limites defectum
Posts: 643
Threads: 120
Joined: Aug 2006
Okay, I'll fix my calls. No big.
My system seems to be off by about 3secs every other day.
What is especially weird is that one sync its only off by a few millisecs and the next sync (26hrs later) it is off by three seconds. Hmmm.