Need accurate timers in Windows AND Linux

We're programming a system which needs to timeout on a serial port within 50ms. Originally I was using the variants of GetLocalTime or gettimeofday for Windows or Linux as appropriate, but I have subsequently found out that these are highly innacurate - at least on Windows.

For Windows I can use QueryPerformanceCounter/Frequency. Great. But not on Linux - this is a cross platform application. But let's stick with Windows for the moment.

There are plenty of examples of QueryPerformanceCounter on the net. But I've yet to find one that takes into account wrap around. I'm sure this must happen at some point, even if it is a 64 bit number. So my first question is, is this code correct for taking into account such wrap-arounds:
v1 := QueryPerformanceCounter(...)
// do some work
v2 := QueryPerformanceCounter(...)
if v2 < v1 then begin
  Result := High(Int64) - v1 + v2;
end else begin
  Result := v2 - v1;

Second question: looks okay (subject to the wrap-around amendments) but is this accurate or reliable enough for Linux? 10ms would be fine.


Geoff M.
Who is Participating?
Hello, Geoff,

Sorry, but I think that you will not be pleased by my answers.  

Windows is NOT a "real-time" operating system, and so you will find that it is not possible to control your time intervals with absolute reliability.  If your timing contraints are not too rigid you might be able to achieve them most of the time.  But there are no guarantees.  If this is good enough, OK.  Otherwise you will need an operating system that supports real-time operations.  For more information see:

Re your first question, I seem to recall that more importantly than any "wrap-around" issue, QueryPerformanceCounter suffered from a problem where the "count" would occassionally "jump" resulting in incorrect results.  I think that the jump was always significant, so for my application I was able to determine that the resulting interval was invalid and simply ignore it.  Applying a similar solution in your case would result in occassionally either missing or mis-identiying a timeout.  If this is acceptable, then it should also handle the far less frequent case of "wrap around".  See;EN-US;Q274323

for details.

Sorry, but I don't have any knowledge about the Linux timers.

Hello omegaomega:

Pc clock ticks only 18 times per second (every 55 milliseconds), so i f you need resolution around 50 ms you can not rely on this clock.

You should get an internal PCI clock card and program your software to read the clock card time instead of the OS clock.

Check this one

You may get lot of cards like this.

gmayoAuthor Commented:
Firstly, we HAVE to use Windows and Linux. Another platform is not viable. Having something which works fairly reliably is important but 100% split second accuracy is not essential. However, a resolution of 55ms is not good enough either.

I wasn't aware of the jumping issue, so I appreciate that link. Quite ironic that one still has to use GetTickCount to determine whether a jump has occurred!

This internal PCI clock card doesn't give any better accuracy or resolution than a standard PC clock. All it's doing is supplying the right time. That is not important in our application as time will be fed from a central atomic time source. The important factor is the relative *intervals* between polling times.

I haven't tried the source code I mentioned on Linux yet, but putting it onto Windows cures my problems - not a single timeout anymore, whereas with GetTickCount and GetTime I was getting numerous.

Thanks, both of you, for the tips.

Geoff M.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.