Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
GetCurMillis immune to system time change?
#1
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...
Reply
#2
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
Software Geek Extraordinaire
Reply
#3
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
Software Geek Extraordinaire
Reply
#4
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...
Reply
#5
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.
Reply
#6
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
Software Geek Extraordinaire
Reply
#7
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.
Reply


Possibly Related Threads...
Thread Author Replies Views Last Post
  System.Runtime.FileSystem documentation missing? rbroders 1 103 11-25-2018, 07:44 PM
Last Post: Dean Roddey
  Down time today Dean Roddey 0 112 11-19-2018, 05:07 PM
Last Post: Dean Roddey
  System Config tom 13 521 11-04-2018, 06:45 PM
Last Post: Dean Roddey
  Unhandled system exception in GUI Thread Shaky 18 945 10-10-2018, 04:23 PM
Last Post: kblagron
  If starting fresh, what is the best garage door system to go with to work with CQC? ghurty 1 387 08-30-2018, 03:23 PM
Last Post: znelbok
  What CQC compatible sound system can support 14 rooms? ghurty 14 1,554 08-05-2018, 07:18 AM
Last Post: zra
  Nice job on the scaling! 1 template for the 1st time! IVB 0 333 07-15-2018, 04:38 PM
Last Post: IVB
  Does anyone have a nice interface set up using the new webRiva system? ghurty 0 365 05-15-2018, 03:13 PM
Last Post: ghurty
  Dim over time potts.mike 8 1,383 04-14-2018, 08:57 AM
Last Post: Dean Roddey
  Simple field change trigger action Bugman 15 4,126 10-23-2017, 11:55 AM
Last Post: Dean Roddey

Forum Jump:


Users browsing this thread: 1 Guest(s)