| OLD | NEW | 
|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include <windows.h> | 5 #include <windows.h> | 
| 6 #include <mmsystem.h> | 6 #include <mmsystem.h> | 
| 7 #include <process.h> | 7 #include <process.h> | 
| 8 | 8 | 
| 9 #include "base/threading/platform_thread.h" | 9 #include "base/threading/platform_thread.h" | 
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" | 
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 107     CloseHandle(g_rollover_test_start); | 107     CloseHandle(g_rollover_test_start); | 
| 108 | 108 | 
| 109     // Teardown | 109     // Teardown | 
| 110     MockTimeTicks::UninstallTicker(); | 110     MockTimeTicks::UninstallTicker(); | 
| 111   } | 111   } | 
| 112 } | 112 } | 
| 113 | 113 | 
| 114 TEST(TimeTicks, SubMillisecondTimers) { | 114 TEST(TimeTicks, SubMillisecondTimers) { | 
| 115   // HighResNow doesn't work on some systems.  Since the product still works | 115   // HighResNow doesn't work on some systems.  Since the product still works | 
| 116   // even if it doesn't work, it makes this entire test questionable. | 116   // even if it doesn't work, it makes this entire test questionable. | 
| 117   if (!TimeTicks::IsHighResClockWorking()) | 117   if (!TimeTicks::IsHighResolution()) | 
| 118     return; | 118     return; | 
| 119 | 119 | 
| 120   const int kRetries = 1000; | 120   const int kRetries = 1000; | 
| 121   bool saw_submillisecond_timer = false; | 121   bool saw_submillisecond_timer = false; | 
| 122 | 122 | 
| 123   // Run kRetries attempts to see a sub-millisecond timer. | 123   // Run kRetries attempts to see a sub-millisecond timer. | 
| 124   for (int index = 0; index < kRetries; index++) { | 124   for (int index = 0; index < kRetries; index++) { | 
| 125     TimeTicks last_time = TimeTicks::HighResNow(); | 125     TimeTicks last_time = TimeTicks::HighResNow(); | 
| 126     TimeDelta delta; | 126     TimeDelta delta; | 
| 127     // Spin until the clock has detected a change. | 127     // Spin until the clock has detected a change. | 
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 176     TestFunc func; | 176     TestFunc func; | 
| 177     const char *description; | 177     const char *description; | 
| 178   }; | 178   }; | 
| 179   // Cheating a bit here:  assumes sizeof(TimeTicks) == sizeof(Time) | 179   // Cheating a bit here:  assumes sizeof(TimeTicks) == sizeof(Time) | 
| 180   // in order to create a single test case list. | 180   // in order to create a single test case list. | 
| 181   COMPILE_ASSERT(sizeof(TimeTicks) == sizeof(Time), | 181   COMPILE_ASSERT(sizeof(TimeTicks) == sizeof(Time), | 
| 182                  test_only_works_with_same_sizes); | 182                  test_only_works_with_same_sizes); | 
| 183   TestCase cases[] = { | 183   TestCase cases[] = { | 
| 184     { reinterpret_cast<TestFunc>(Time::Now), "Time::Now" }, | 184     { reinterpret_cast<TestFunc>(Time::Now), "Time::Now" }, | 
| 185     { TimeTicks::Now, "TimeTicks::Now" }, | 185     { TimeTicks::Now, "TimeTicks::Now" }, | 
| 186     { TimeTicks::HighResNow, "TimeTicks::HighResNow" }, | 186     { TimeTicks::NowFromSystemTraceTime, "TimeTicks::NowFromSystemTraceTime" }, | 
| 187     { NULL, "" } | 187     { NULL, "" } | 
| 188   }; | 188   }; | 
| 189 | 189 | 
| 190   int test_case = 0; | 190   int test_case = 0; | 
| 191   while (cases[test_case].func) { | 191   while (cases[test_case].func) { | 
| 192     TimeTicks start = TimeTicks::HighResNow(); | 192     TimeTicks start = TimeTicks::HighResNow(); | 
| 193     for (int index = 0; index < kLoops; index++) | 193     for (int index = 0; index < kLoops; index++) | 
| 194       cases[test_case].func(); | 194       cases[test_case].func(); | 
| 195     TimeTicks stop = TimeTicks::HighResNow(); | 195     TimeTicks stop = TimeTicks::HighResNow(); | 
| 196     // Turning off the check for acceptible delays.  Without this check, | 196     // Turning off the check for acceptible delays.  Without this check, | 
| 197     // the test really doesn't do much other than measure.  But the | 197     // the test really doesn't do much other than measure.  But the | 
| 198     // measurements are still useful for testing timers on various platforms. | 198     // measurements are still useful for testing timers on various platforms. | 
| 199     // The reason to remove the check is because the tests run on many | 199     // The reason to remove the check is because the tests run on many | 
| 200     // buildbots, some of which are VMs.  These machines can run horribly | 200     // buildbots, some of which are VMs.  These machines can run horribly | 
| 201     // slow, and there is really no value for checking against a max timer. | 201     // slow, and there is really no value for checking against a max timer. | 
| 202     //const int kMaxTime = 35;  // Maximum acceptible milliseconds for test. | 202     //const int kMaxTime = 35;  // Maximum acceptible milliseconds for test. | 
| 203     //EXPECT_LT((stop - start).InMilliseconds(), kMaxTime); | 203     //EXPECT_LT((stop - start).InMilliseconds(), kMaxTime); | 
| 204     printf("%s: %1.2fus per call\n", cases[test_case].description, | 204     printf("%s: %1.2fus per call\n", cases[test_case].description, | 
| 205       (stop - start).InMillisecondsF() * 1000 / kLoops); | 205       (stop - start).InMillisecondsF() * 1000 / kLoops); | 
| 206     test_case++; | 206     test_case++; | 
| 207   } | 207   } | 
| 208 } | 208 } | 
| 209 | 209 | 
| 210 // http://crbug.com/396384 | 210 TEST(TimeTicks, FromQPCValue) { | 
| 211 TEST(TimeTicks, DISABLED_Drift) { | 211   if (!TimeTicks::IsHighResolution()) | 
| 212   // If QPC is disabled, this isn't measuring anything. |  | 
| 213   if (!TimeTicks::IsHighResClockWorking()) |  | 
| 214     return; | 212     return; | 
| 215 | 213 | 
| 216   const int kIterations = 100; | 214   const int kIterations = 100; | 
| 217   int64 total_drift = 0; | 215 | 
|  | 216   LARGE_INTEGER frequency; | 
|  | 217   ASSERT_TRUE(QueryPerformanceFrequency(&frequency)); | 
|  | 218   const int64 ticks_per_second = frequency.QuadPart; | 
|  | 219 | 
|  | 220   TimeTicks start_time = TimeTicks::Now(); | 
|  | 221   LARGE_INTEGER start_ticks; | 
|  | 222   ASSERT_TRUE(QueryPerformanceCounter(&start_ticks)); | 
|  | 223   LARGE_INTEGER ticks = start_ticks; | 
|  | 224   int64 ticks_increment = 10; | 
| 218 | 225 | 
| 219   for (int i = 0; i < kIterations; ++i) { | 226   for (int i = 0; i < kIterations; ++i) { | 
| 220     int64 drift_microseconds = TimeTicks::GetQPCDriftMicroseconds(); | 227     ticks.QuadPart += ticks_increment; | 
|  | 228     ticks_increment = ticks_increment * 6 / 5; | 
| 221 | 229 | 
| 222     // Make sure the drift never exceeds our limit. | 230     const int64 ticks_advanced = ticks.QuadPart - start_ticks.QuadPart; | 
| 223     EXPECT_LT(drift_microseconds, 50000); | 231     const TimeTicks expected_value = start_time + | 
| 224 | 232         TimeDelta::FromMicroseconds( | 
| 225     // Sleep for a few milliseconds (note that it means 1000 microseconds). | 233             ticks_advanced * Time::kMicrosecondsPerSecond / ticks_per_second); | 
| 226     // If we check the drift too frequently, it's going to increase | 234     const TimeTicks value = TimeTicks::FromQPCValue(ticks.QuadPart); | 
| 227     // monotonically, making our measurement less realistic. | 235     EXPECT_GT(1.0, (value - expected_value).magnitude().InMillisecondsF()) | 
| 228     base::PlatformThread::Sleep( | 236         << "iteration: " << i; | 
| 229         base::TimeDelta::FromMilliseconds((i % 2 == 0) ? 1 : 2)); |  | 
| 230 |  | 
| 231     total_drift += drift_microseconds; |  | 
| 232   } | 237   } | 
| 233 |  | 
| 234   // Sanity check. We expect some time drift to occur, especially across |  | 
| 235   // the number of iterations we do. |  | 
| 236   EXPECT_LT(0, total_drift); |  | 
| 237 |  | 
| 238   printf("average time drift in microseconds: %lld\n", |  | 
| 239          total_drift / kIterations); |  | 
| 240 } | 238 } | 
| 241 |  | 
| 242 int64 QPCValueToMicrosecondsSafely(LONGLONG qpc_value, |  | 
| 243                                    int64 ticks_per_second) { |  | 
| 244   int64 whole_seconds = qpc_value / ticks_per_second; |  | 
| 245   int64 leftover_ticks = qpc_value % ticks_per_second; |  | 
| 246   int64 microseconds = (whole_seconds * Time::kMicrosecondsPerSecond) + |  | 
| 247                        ((leftover_ticks * Time::kMicrosecondsPerSecond) / |  | 
| 248                         ticks_per_second); |  | 
| 249   return microseconds; |  | 
| 250 } |  | 
| 251 |  | 
| 252 TEST(TimeTicks, FromQPCValue) { |  | 
| 253   if (!TimeTicks::IsHighResClockWorking()) |  | 
| 254     return; |  | 
| 255   LARGE_INTEGER frequency; |  | 
| 256   QueryPerformanceFrequency(&frequency); |  | 
| 257   int64 ticks_per_second = frequency.QuadPart; |  | 
| 258   LONGLONG qpc_value = Time::kQPCOverflowThreshold; |  | 
| 259   TimeTicks expected_value = TimeTicks::FromInternalValue( |  | 
| 260     QPCValueToMicrosecondsSafely(qpc_value + 1, ticks_per_second)); |  | 
| 261   EXPECT_EQ(expected_value, |  | 
| 262             TimeTicks::FromQPCValue(qpc_value + 1)); |  | 
| 263   expected_value = TimeTicks::FromInternalValue( |  | 
| 264     QPCValueToMicrosecondsSafely(qpc_value, ticks_per_second)); |  | 
| 265   EXPECT_EQ(expected_value, |  | 
| 266             TimeTicks::FromQPCValue(qpc_value)); |  | 
| 267   expected_value = TimeTicks::FromInternalValue( |  | 
| 268     QPCValueToMicrosecondsSafely(qpc_value - 1, ticks_per_second)); |  | 
| 269   EXPECT_EQ(expected_value, |  | 
| 270             TimeTicks::FromQPCValue(qpc_value - 1)); |  | 
| 271 } |  | 
| OLD | NEW | 
|---|