How to stop time from running backwards on Linux?
Asked Answered
L

5

24

Here's a little test I've written to verify that time does indeed only run forwards in Linux.

#include <time.h>
#include <sys/time.h>  

bool timeGoesForwardTest2()
{
   timeval tv1, tv2;   
   double startTime = getTimeSeconds();  // my function

   while ( getTimeSeconds() - startTime < 5 )
   {
      gettimeofday( &tv1, NULL );  
      gettimeofday( &tv2, NULL );  

      if ( tv2.tv_usec == tv1.tv_usec &&
           tv2.tv_sec == tv1.tv_sec )
      {
         continue;  // Equal times are allowed.
      }

      // tv2 should be greater than tv1
      if ( !( tv2.tv_usec>tv1.tv_usec ||
              tv2.tv_sec-1 == tv1.tv_sec ) )
      {
         printf( "tv1: %d %d\n", int( tv1.tv_sec ), int( tv1.tv_usec ) );
         printf( "tv2: %d %d\n", int( tv2.tv_sec ), int( tv2.tv_usec ) );
         return false;
      }         
   }
   return true;
}

Test fails with the result.

 tv1: 1296011067 632550
 tv2: 1296011067 632549

ummm....

Why does this happen?

Here's my setup:

Linux version 2.6.35-22-generic (buildd@rothera) (gcc version 4.4.5 (Ubuntu/Linaro 4.4.4-14ubuntu4) ) #33-Ubuntu SMP Sun Sep 19 20:34:50 UTC 2010 (Ubuntu 2.6.35-22.33-generic 2.6.35.4)
... running inside VirtualBox 3.2.12, in Windows 7.
Liechtenstein answered 26/1, 2011 at 3:11 Comment(10)
It may have to do with the VM. Have you tried doing this with an actual Linux install?Schumer
Make sure you are checking for integer rollover on tv_sec and tv_usec whenever doing any calculations with them.Shanney
I suspect it's because the time calls go out to two different cores on your CPU and one of them is in the vicinity of a miniature black hole. Get out of the house. As quick as you can. Seriously!Markman
Turn the CMOS battery around... polarity must be wrong.Andry
The bottom-left panel of xkcd.com/821 comes to mind.Lenard
@Markman - Looks like someone's coding for the Large Hadron Collider.Arrogance
Perhaps the CPU is running precisely 88 mph?Gagliardi
Since gettimeofday has been removed in POSIX.1-2008, might as well use clock_gettime, also because it provides nsec granularity. (And not just because of the monotonicity option.)Wenwenceslaus
Your clock might be running backwards but hopefully time itself is unaffected by your choice of operating system.Mindi
Try spinning your little spinning top thing, see if it falls over.Ripping
L
17

There is an open issue at the VirtualBox Bug Tracker. They link to a blog post stating why you shouldn't use gettimeofday() to measure the passage of time:

The most portable way to measure time correctly seems to be clock_gettime(CLOCK_MONOTONIC, ...)

Lushy answered 26/1, 2011 at 3:25 Comment(4)
The bugtracker link also points out that CLOCK_MONOTONIC exhibits the same problem - as does FreeBSD running under VirtualBox. It appears to be a VirtualBox bug.Fingerboard
Time on VMs seems to be pretty fruity anyway. My VMWare install at work suddenly decided it was going to tick time at 1/2 the correct rate.Compilation
This seems to be right. gettimeofday is problematic for me on native and virtual machines. clock_gettime however also seems to fail for VirtualBox. Bug is in VirtualBox.Liechtenstein
It's a Linux kernel bug. None of the linux kernel timers seem to work right in a VM, because of the enormous effort they go to to avoid using the BIOS calls for the current time, which the VM answers to.Dundee
A
30

gettimeofday() is not guaranteed to be monotonic. Use clock_gettime(CLOCK_MONOTONIC) if you need that guarantee.

Abate answered 26/1, 2011 at 3:20 Comment(1)
This is true, but the bugtracker link posted by @vz0 says that the same issue occurs under VirtualBox with CLOCK_MONOTONIC, so there is also a bug here.Fingerboard
L
17

There is an open issue at the VirtualBox Bug Tracker. They link to a blog post stating why you shouldn't use gettimeofday() to measure the passage of time:

The most portable way to measure time correctly seems to be clock_gettime(CLOCK_MONOTONIC, ...)

Lushy answered 26/1, 2011 at 3:25 Comment(4)
The bugtracker link also points out that CLOCK_MONOTONIC exhibits the same problem - as does FreeBSD running under VirtualBox. It appears to be a VirtualBox bug.Fingerboard
Time on VMs seems to be pretty fruity anyway. My VMWare install at work suddenly decided it was going to tick time at 1/2 the correct rate.Compilation
This seems to be right. gettimeofday is problematic for me on native and virtual machines. clock_gettime however also seems to fail for VirtualBox. Bug is in VirtualBox.Liechtenstein
It's a Linux kernel bug. None of the linux kernel timers seem to work right in a VM, because of the enormous effort they go to to avoid using the BIOS calls for the current time, which the VM answers to.Dundee
S
10

Machine timers on most machines only have about 15 usec precision (even to native code). Time going 'backward' is odd, but you really can't rely on that level (1 usec) anyway. (Also note: there is a difference between precision and accuracy; the accuracy of most timers is worse than its precision). The use of a virtual machine may aggravate this as well.

Update: Typo

Sprag answered 26/1, 2011 at 3:17 Comment(1)
Great point about precision versus accuracy. Case in point: RDTSC has extreme precision (sub-nanosecond on many modern machines) yet potentially much worse accuracy than any normal timekeeping functions.Abate
M
5

It's not that it's running backwards. It'd be better to say that it is not reporting the correct time. This is because computers, without the aid of a dedicated timing subsystem, simply are not capable of reporting time very accurately in single millisecond intervals.

The precision will vary with hardware, the OS and even the power supply. Here is an article for starters. A bit old but communicates the idea nicely.

Miracidium answered 26/1, 2011 at 3:16 Comment(2)
This answer is nonsense. Any modern Unix-like system will give precision to 10 millisecond resolution or better, and nanosecond resolution is not uncommon. I hear Windows doesn't do a bad job either...Daumier
@R: I was thinking along the lines of old Windows interrupt timers when i quoted the original resolution. Updated my answer for modern times...Miracidium
O
1

Time should not run backwards on real hardware; on a VM your mileage may vary.

In any case, your application should probably not assume that time doesn't run backwards by a very small amount (think, maybe 1 second).

Yes, clock_gettime is good but even that could run backwards in the case of faulty hardware (or a VM, as in your example).

I have seen a hardware bug make time run backwards (albeit very occasionally), it was a cause of some very peculiar problems.

In particular, anything which involves comparing file timestamps will go wrong when time goes backwards.

Organization answered 26/1, 2011 at 11:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.