15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <mmsystem.h> 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <process.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeTicks; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MockTimeTicks : public TimeTicks { 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static DWORD Ticker() { 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(InterlockedIncrement(&ticker_)); 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void InstallTicker() { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_tick_function_ = SetMockTickFunction(&Ticker); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ticker_ = -5; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void UninstallTicker() { 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetMockTickFunction(old_tick_function_); 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static volatile LONG ticker_; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static TickFunctionType old_tick_function_; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)volatile LONG MockTimeTicks::ticker_; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MockTimeTicks::TickFunctionType MockTimeTicks::old_tick_function_; 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HANDLE g_rollover_test_start; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned __stdcall RolloverTestThreadMain(void* param) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 counter = reinterpret_cast<int64>(param); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD rv = WaitForSingleObject(g_rollover_test_start, INFINITE); 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, WAIT_OBJECT_0); 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks last = TimeTicks::Now(); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int index = 0; index < counter; index++) { 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks now = TimeTicks::Now(); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 milliseconds = (now - last).InMilliseconds(); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This is a tight loop; we could have looped faster than our 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // measurements, so the time might be 0 millis. 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(milliseconds, 0); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(milliseconds, 250); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last = now; 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return 0; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeTicks, WinRollover) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The internal counter rolls over at ~49days. We'll use a mock 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // timer to test this case. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Basic test algorithm: 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 1) Set clock to rollover - N 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 2) Create N threads 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 3) Start the threads 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 4) Each thread loops through TimeTicks() N times 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 5) Each thread verifies integrity of result. 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kThreads = 8; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Use int64 so we can cast into a void* without a compiler warning. 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int64 kChecks = 10; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It takes a lot of iterations to reproduce the bug! 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (See bug 1081395) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int loop = 0; loop < 4096; loop++) { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockTimeTicks::InstallTicker(); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) g_rollover_test_start = CreateEvent(0, TRUE, FALSE, 0); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HANDLE threads[kThreads]; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int index = 0; index < kThreads; index++) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* argument = reinterpret_cast<void*>(kChecks); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned thread_id; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) threads[index] = reinterpret_cast<HANDLE>( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _beginthreadex(NULL, 0, RolloverTestThreadMain, argument, 0, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &thread_id)); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NE((HANDLE)NULL, threads[index]); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start! 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetEvent(g_rollover_test_start); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Wait for threads to finish 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int index = 0; index < kThreads; index++) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD rv = WaitForSingleObject(threads[index], INFINITE); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(rv, WAIT_OBJECT_0); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CloseHandle(g_rollover_test_start); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Teardown 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MockTimeTicks::UninstallTicker(); 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeTicks, SubMillisecondTimers) { 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // HighResNow doesn't work on some systems. Since the product still works 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // even if it doesn't work, it makes this entire test questionable. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!TimeTicks::IsHighResClockWorking()) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kRetries = 1000; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool saw_submillisecond_timer = false; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Run kRetries attempts to see a sub-millisecond timer. 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int index = 0; index < 1000; index++) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks last_time = TimeTicks::HighResNow(); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeDelta delta; 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Spin until the clock has detected a change. 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delta = TimeTicks::HighResNow() - last_time; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (delta.InMicroseconds() == 0); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (delta.InMicroseconds() < 1000) { 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) saw_submillisecond_timer = true; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(saw_submillisecond_timer); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeTicks, TimeGetTimeCaps) { 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test some basic assumptions that we expect about how timeGetDevCaps works. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TIMECAPS caps; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MMRESULT status = timeGetDevCaps(&caps, sizeof(caps)); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(TIMERR_NOERROR, status); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != TIMERR_NOERROR) { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("Could not get timeGetDevCaps\n"); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(static_cast<int>(caps.wPeriodMin), 1); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(static_cast<int>(caps.wPeriodMax), 1); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GE(static_cast<int>(caps.wPeriodMin), 1); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(static_cast<int>(caps.wPeriodMax), 1); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("timeGetTime range is %d to %dms\n", caps.wPeriodMin, 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) caps.wPeriodMax); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeTicks, QueryPerformanceFrequency) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test some basic assumptions that we expect about QPC. 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LARGE_INTEGER frequency; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BOOL rv = QueryPerformanceFrequency(&frequency); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(TRUE, rv); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(frequency.QuadPart, 1000000); // Expect at least 1MHz 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("QueryPerformanceFrequency is %5.2fMHz\n", 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frequency.QuadPart / 1000000.0); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeTicks, TimerPerformance) { 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify that various timer mechanisms can always complete quickly. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: This is a somewhat arbitrary test. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kLoops = 10000; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Due to the fact that these run on bbots, which are horribly slow, 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we can't really make any guarantees about minimum runtime. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Really, we want these to finish in ~10ms, and that is generous. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kMaxTime = 35; // Maximum acceptible milliseconds for test. 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef TimeTicks (*TestFunc)(); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct TestCase { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestFunc func; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char *description; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Cheating a bit here: assumes sizeof(TimeTicks) == sizeof(Time) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in order to create a single test case list. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COMPILE_ASSERT(sizeof(TimeTicks) == sizeof(Time), 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_only_works_with_same_sizes); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestCase cases[] = { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { reinterpret_cast<TestFunc>(Time::Now), "Time::Now" }, 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { TimeTicks::Now, "TimeTicks::Now" }, 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { TimeTicks::HighResNow, "TimeTicks::HighResNow" }, 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { NULL, "" } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int test_case = 0; 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (cases[test_case].func) { 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks start = TimeTicks::HighResNow(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int index = 0; index < kLoops; index++) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cases[test_case].func(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TimeTicks stop = TimeTicks::HighResNow(); 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Turning off the check for acceptible delays. Without this check, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the test really doesn't do much other than measure. But the 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // measurements are still useful for testing timers on various platforms. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The reason to remove the check is because the tests run on many 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buildbots, some of which are VMs. These machines can run horribly 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // slow, and there is really no value for checking against a max timer. 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) //EXPECT_LT((stop - start).InMilliseconds(), kMaxTime); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("%s: %1.2fus per call\n", cases[test_case].description, 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (stop - start).InMillisecondsF() * 1000 / kLoops); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) test_case++; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(TimeTicks, Drift) { 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If QPC is disabled, this isn't measuring anything. 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!TimeTicks::IsHighResClockWorking()) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kIterations = 100; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 total_drift = 0; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kIterations; ++i) { 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 drift_microseconds = TimeTicks::GetQPCDriftMicroseconds(); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the drift never exceeds our limit. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(drift_microseconds, 50000); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sleep for a few milliseconds (note that it means 1000 microseconds). 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If we check the drift too frequently, it's going to increase 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // monotonically, making our measurement less realistic. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::PlatformThread::Sleep( 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds((i % 2 == 0) ? 1 : 2)); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_drift += drift_microseconds; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sanity check. We expect some time drift to occur, especially across 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the number of iterations we do. 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(0, total_drift); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) printf("average time drift in microseconds: %lld\n", 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_drift / kIterations); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 240