"Make Chrome your default browser" should now appear as a checkbox at the bottom...
[chromium-blink-merge.git] / base / time_unittest_win.cc
blob87cf698fe361a444e7c147bf983bd2b37485ab1d
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.
5 #include <windows.h>
6 #include <process.h>
8 #include "base/time.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 namespace {
13 class MockTimeTicks : public TimeTicks {
14 public:
15 static DWORD Ticker() {
16 return static_cast<int>(InterlockedIncrement(&ticker_));
19 static void InstallTicker() {
20 old_tick_function_ = SetMockTickFunction(&Ticker);
21 ticker_ = -5;
24 static void UninstallTicker() {
25 SetMockTickFunction(old_tick_function_);
28 private:
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);
49 last = now;
51 return 0;
54 } // namespace
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!
71 // (See bug 1081395)
72 for (int loop = 0; loop < 4096; loop++) {
73 // Setup
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);
80 unsigned thread_id;
81 threads[index] = reinterpret_cast<HANDLE>(
82 _beginthreadex(NULL, 0, RolloverTestThreadMain, argument, 0,
83 &thread_id));
84 EXPECT_NE((HANDLE)NULL, threads[index]);
87 // Start!
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);
98 // Teardown
99 MockTimeTicks::UninstallTicker();