1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
9 #include "testing/gtest/include/gtest/gtest.h"
13 class MockTimeTicks
: public TimeTicks
{
15 static DWORD
Ticker() {
16 return static_cast<int>(InterlockedIncrement(&ticker_
));
19 static void InstallTicker() {
20 old_tick_function_
= SetMockTickFunction(&Ticker
);
24 static void UninstallTicker() {
25 SetMockTickFunction(old_tick_function_
);
29 static volatile LONG ticker_
;
30 static TickFunctionType old_tick_function_
;
33 volatile LONG
MockTimeTicks::ticker_
;
34 MockTimeTicks::TickFunctionType
MockTimeTicks::old_tick_function_
;
36 HANDLE g_rollover_test_start
;
38 unsigned __stdcall
RolloverTestThreadMain(void* param
) {
39 int64 counter
= reinterpret_cast<int64
>(param
);
40 DWORD rv
= WaitForSingleObject(g_rollover_test_start
, INFINITE
);
41 EXPECT_EQ(rv
, WAIT_OBJECT_0
);
43 TimeTicks last
= TimeTicks::Now();
44 for (int index
= 0; index
< counter
; index
++) {
45 TimeTicks now
= TimeTicks::Now();
46 int64 milliseconds
= (now
- last
).InMilliseconds();
47 EXPECT_GT(milliseconds
, 0);
48 EXPECT_LT(milliseconds
, 250);
56 TEST(TimeTicks
, WinRollover
) {
57 // The internal counter rolls over at ~49days. We'll use a mock
58 // timer to test this case.
59 // Basic test algorithm:
60 // 1) Set clock to rollover - N
61 // 2) Create N threads
62 // 3) Start the threads
63 // 4) Each thread loops through TimeTicks() N times
64 // 5) Each thread verifies integrity of result.
66 const int kThreads
= 8;
67 // Use int64 so we can cast into a void* without a compiler warning.
68 const int64 kChecks
= 10;
70 // It takes a lot of iterations to reproduce the bug!
72 for (int loop
= 0; loop
< 4096; loop
++) {
74 MockTimeTicks::InstallTicker();
75 g_rollover_test_start
= CreateEvent(0, TRUE
, FALSE
, 0);
76 HANDLE threads
[kThreads
];
78 for (int index
= 0; index
< kThreads
; index
++) {
79 void* argument
= reinterpret_cast<void*>(kChecks
);
81 threads
[index
] = reinterpret_cast<HANDLE
>(
82 _beginthreadex(NULL
, 0, RolloverTestThreadMain
, argument
, 0,
84 EXPECT_NE((HANDLE
)NULL
, threads
[index
]);
88 SetEvent(g_rollover_test_start
);
90 // Wait for threads to finish
91 for (int index
= 0; index
< kThreads
; index
++) {
92 DWORD rv
= WaitForSingleObject(threads
[index
], INFINITE
);
93 EXPECT_EQ(rv
, WAIT_OBJECT_0
);
96 CloseHandle(g_rollover_test_start
);
99 MockTimeTicks::UninstallTicker();