Fix public issue #30: Stop using gettimeofday() altogether on Win32,
as MSVC doesn't include it. Replace with QueryPerformanceCounter(),
which is monotonic and probably reasonably high-resolution.
(Some machines have traditionally had bugs in QPC, but they should
be relatively rare these days, and there's really no much better
alternative that I know of.)

R=csilvers
DELTA=74  (55 added, 19 deleted, 0 changed)


Revision created by MOE tool push_codebase.
MOE_MIGRATION=1556


git-svn-id: https://snappy.googlecode.com/svn/trunk@31 03e5f5b5-db94-4691-08a0-1a8bf15f6143
diff --git a/snappy-test.cc b/snappy-test.cc
index b608516..c9aae2e 100644
--- a/snappy-test.cc
+++ b/snappy-test.cc
@@ -74,21 +74,22 @@
   benchmark_cpu_time_us = 0;
 }
 
-struct timeval benchmark_start_real;
-
 #ifdef WIN32
+LARGE_INTEGER benchmark_start_real;
 FILETIME benchmark_start_cpu;
 #else  // WIN32
+struct timeval benchmark_start_real;
 struct rusage benchmark_start_cpu;
 #endif  // WIN32
 
 void StartBenchmarkTiming() {
-  gettimeofday(&benchmark_start_real, NULL);
 #ifdef WIN32
+  QueryPerformanceCounter(&benchmark_start_real);
   FILETIME dummy;
   CHECK(GetProcessTimes(
       GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_start_cpu));
 #else
+  gettimeofday(&benchmark_start_real, NULL);
   if (getrusage(RUSAGE_SELF, &benchmark_start_cpu) == -1) {
     perror("getrusage(RUSAGE_SELF)");
     exit(1);
@@ -101,14 +102,18 @@
   if (!benchmark_running) {
     return;
   }
-  struct timeval benchmark_stop_real;
-  gettimeofday(&benchmark_stop_real, NULL);
-  benchmark_real_time_us +=
-      1000000 * (benchmark_stop_real.tv_sec - benchmark_start_real.tv_sec);
-  benchmark_real_time_us +=
-      (benchmark_stop_real.tv_usec - benchmark_start_real.tv_usec);
 
 #ifdef WIN32
+  LARGE_INTEGER benchmark_stop_real;
+  LARGE_INTEGER benchmark_frequency;
+  QueryPerformanceCounter(&benchmark_stop_real);
+  QueryPerformanceFrequency(&benchmark_frequency);
+
+  double elapsed_real = static_cast<double>(
+      benchmark_stop_real.QuadPart - benchmark_start_real.QuadPart) /
+      benchmark_frequency.QuadPart;
+  benchmark_real_time_us += elapsed_real * 1e6 + 0.5;
+
   FILETIME benchmark_stop_cpu, dummy;
   CHECK(GetProcessTimes(
       GetCurrentProcess(), &dummy, &dummy, &dummy, &benchmark_stop_cpu));
@@ -124,6 +129,13 @@
   benchmark_cpu_time_us +=
       (stop_ulargeint.QuadPart - start_ulargeint.QuadPart + 5) / 10;
 #else  // WIN32
+  struct timeval benchmark_stop_real;
+  gettimeofday(&benchmark_stop_real, NULL);
+  benchmark_real_time_us +=
+      1000000 * (benchmark_stop_real.tv_sec - benchmark_start_real.tv_sec);
+  benchmark_real_time_us +=
+      (benchmark_stop_real.tv_usec - benchmark_start_real.tv_usec);
+
   struct rusage benchmark_stop_cpu;
   if (getrusage(RUSAGE_SELF, &benchmark_stop_cpu) == -1) {
     perror("getrusage(RUSAGE_SELF)");
diff --git a/snappy-test.h b/snappy-test.h
index 18f5b1b..649f26e 100644
--- a/snappy-test.h
+++ b/snappy-test.h
@@ -46,6 +46,11 @@
 
 #include <sys/time.h>
 
+#ifdef HAVE_WINDOWS_H
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#endif
+
 #include <string>
 
 #ifdef HAVE_GTEST
@@ -241,15 +246,30 @@
   CycleTimer() : real_time_us_(0) {}
 
   void Start() {
+#ifdef WIN32
+    QueryPerformanceCounter(&start_);
+#else
     gettimeofday(&start_, NULL);
+#endif
   }
 
   void Stop() {
+#ifdef WIN32
+    LARGE_INTEGER stop;
+    LARGE_INTEGER frequency;
+    QueryPerformanceCounter(&stop);
+    QueryPerformanceFrequency(&frequency);
+
+    double elapsed = static_cast<double>(stop.QuadPart - start_.QuadPart) /
+        frequency.QuadPart;
+    real_time_us_ += elapsed * 1e6 + 0.5;
+#else
     struct timeval stop;
     gettimeofday(&stop, NULL);
 
     real_time_us_ += 1000000 * (stop.tv_sec - start_.tv_sec);
     real_time_us_ += (stop.tv_usec - start_.tv_usec);
+#endif
   }
 
   double Get() {
@@ -258,7 +278,11 @@
 
  private:
   int64 real_time_us_;
+#ifdef WIN32
+  LARGE_INTEGER start_;
+#else
   struct timeval start_;
+#endif
 };
 
 // Minimalistic microbenchmark framework.