Fix backwards clock on tsc source with Linux
authorJens Axboe <jens.axboe@oracle.com>
Thu, 13 Nov 2008 11:07:20 +0000 (12:07 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Thu, 13 Nov 2008 11:07:20 +0000 (12:07 +0100)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
gettime.c

index 2753faecb02d0596b1898346a46bf7f1d9e44873..80eeaf14bcbb75293a1621382eaa8d765fe2d015 100644 (file)
--- a/gettime.c
+++ b/gettime.c
@@ -10,6 +10,8 @@
 #include "hash.h"
 
 static int clock_gettime_works;
 #include "hash.h"
 
 static int clock_gettime_works;
+static struct timeval last_tv;
+static int last_tv_valid;
 
 #ifdef FIO_DEBUG_TIME
 
 
 #ifdef FIO_DEBUG_TIME
 
@@ -128,4 +130,18 @@ gtod:
                tp->tv_sec = ts.tv_sec;
                tp->tv_usec = ts.tv_nsec / 1000;
        }
                tp->tv_sec = ts.tv_sec;
                tp->tv_usec = ts.tv_nsec / 1000;
        }
+
+       /*
+        * If Linux is using the tsc clock on non-synced processors,
+        * sometimes time can appear to drift backwards. Fix that up.
+        */
+       if (last_tv_valid) {
+               if (tp->tv_sec < last_tv.tv_sec)
+                       tp->tv_sec = last_tv.tv_sec;
+               else if (last_tv.tv_sec == tp->tv_sec &&
+                        tp->tv_usec < last_tv.tv_usec)
+                       tp->tv_usec = last_tv.tv_usec;
+       }
+       last_tv_valid = 1;
+       memcpy(&last_tv, tp, sizeof(*tp));
 }
 }