OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 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 | 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 <process.h> | 7 #include <process.h> |
7 | 8 |
8 #include "base/time.h" | 9 #include "base/time.h" |
9 #include "testing/gtest/include/gtest/gtest.h" | 10 #include "testing/gtest/include/gtest/gtest.h" |
10 | 11 |
11 namespace { | 12 namespace { |
12 | 13 |
13 class MockTimeTicks : public TimeTicks { | 14 class MockTimeTicks : public TimeTicks { |
14 public: | 15 public: |
15 static DWORD Ticker() { | 16 static DWORD Ticker() { |
(...skipping 21 matching lines...) Expand all Loading... |
37 | 38 |
38 unsigned __stdcall RolloverTestThreadMain(void* param) { | 39 unsigned __stdcall RolloverTestThreadMain(void* param) { |
39 int64 counter = reinterpret_cast<int64>(param); | 40 int64 counter = reinterpret_cast<int64>(param); |
40 DWORD rv = WaitForSingleObject(g_rollover_test_start, INFINITE); | 41 DWORD rv = WaitForSingleObject(g_rollover_test_start, INFINITE); |
41 EXPECT_EQ(rv, WAIT_OBJECT_0); | 42 EXPECT_EQ(rv, WAIT_OBJECT_0); |
42 | 43 |
43 TimeTicks last = TimeTicks::Now(); | 44 TimeTicks last = TimeTicks::Now(); |
44 for (int index = 0; index < counter; index++) { | 45 for (int index = 0; index < counter; index++) { |
45 TimeTicks now = TimeTicks::Now(); | 46 TimeTicks now = TimeTicks::Now(); |
46 int64 milliseconds = (now - last).InMilliseconds(); | 47 int64 milliseconds = (now - last).InMilliseconds(); |
47 EXPECT_GT(milliseconds, 0); | 48 // This is a tight loop; we could have looped faster than our |
| 49 // measurements, so the time might be 0 millis. |
| 50 EXPECT_GE(milliseconds, 0); |
48 EXPECT_LT(milliseconds, 250); | 51 EXPECT_LT(milliseconds, 250); |
49 last = now; | 52 last = now; |
50 } | 53 } |
51 return 0; | 54 return 0; |
52 } | 55 } |
53 | 56 |
54 } // namespace | 57 } // namespace |
55 | 58 |
56 TEST(TimeTicks, WinRollover) { | 59 TEST(TimeTicks, WinRollover) { |
57 // The internal counter rolls over at ~49days. We'll use a mock | 60 // The internal counter rolls over at ~49days. We'll use a mock |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 DWORD rv = WaitForSingleObject(threads[index], INFINITE); | 95 DWORD rv = WaitForSingleObject(threads[index], INFINITE); |
93 EXPECT_EQ(rv, WAIT_OBJECT_0); | 96 EXPECT_EQ(rv, WAIT_OBJECT_0); |
94 } | 97 } |
95 | 98 |
96 CloseHandle(g_rollover_test_start); | 99 CloseHandle(g_rollover_test_start); |
97 | 100 |
98 // Teardown | 101 // Teardown |
99 MockTimeTicks::UninstallTicker(); | 102 MockTimeTicks::UninstallTicker(); |
100 } | 103 } |
101 } | 104 } |
| 105 |
| 106 TEST(TimeTicks, SubMillisecondTimers) { |
| 107 // Loop for a bit getting timers quickly. We want to |
| 108 // see at least one case where we get a new sample in |
| 109 // less than one millisecond. |
| 110 bool saw_submillisecond_timer = false; |
| 111 int64 min_timer = 1000; |
| 112 TimeTicks last_time = TimeTicks::HighResNow(); |
| 113 for (int index = 0; index < 1000; index++) { |
| 114 TimeTicks now = TimeTicks::HighResNow(); |
| 115 TimeDelta delta = now - last_time; |
| 116 if (delta.InMicroseconds() > 0 && |
| 117 delta.InMicroseconds() < 1000) { |
| 118 if (min_timer > delta.InMicroseconds()) |
| 119 min_timer = delta.InMicroseconds(); |
| 120 saw_submillisecond_timer = true; |
| 121 } |
| 122 last_time = now; |
| 123 } |
| 124 EXPECT_TRUE(saw_submillisecond_timer); |
| 125 printf("Min timer is: %dus\n", min_timer); |
| 126 } |
| 127 |
| 128 TEST(TimeTicks, TimeGetTimeCaps) { |
| 129 // Test some basic assumptions that we expect about how timeGetDevCaps works. |
| 130 |
| 131 TIMECAPS caps; |
| 132 MMRESULT status = timeGetDevCaps(&caps, sizeof(caps)); |
| 133 EXPECT_EQ(TIMERR_NOERROR, status); |
| 134 if (status != TIMERR_NOERROR) { |
| 135 printf("Could not get timeGetDevCaps\n"); |
| 136 return; |
| 137 } |
| 138 |
| 139 EXPECT_GE(static_cast<int>(caps.wPeriodMin), 1); |
| 140 EXPECT_GT(static_cast<int>(caps.wPeriodMax), 1); |
| 141 EXPECT_GE(static_cast<int>(caps.wPeriodMin), 1); |
| 142 EXPECT_GT(static_cast<int>(caps.wPeriodMax), 1); |
| 143 printf("timeGetTime range is %d to %dms\n", caps.wPeriodMin, |
| 144 caps.wPeriodMax); |
| 145 } |
| 146 |
| 147 TEST(TimeTicks, QueryPerformanceFrequency) { |
| 148 // Test some basic assumptions that we expect about QPC. |
| 149 |
| 150 LARGE_INTEGER frequency; |
| 151 BOOL rv = QueryPerformanceFrequency(&frequency); |
| 152 EXPECT_EQ(TRUE, rv); |
| 153 EXPECT_GT(frequency.QuadPart, 1000000); // Expect at least 1MHz |
| 154 printf("QueryPerformanceFrequency is %5.2fMHz\n", |
| 155 frequency.QuadPart / 1000000.0); |
| 156 } |
| 157 |
| 158 TEST(TimeTicks, TimerPerformance) { |
| 159 // Verify that various timer mechanisms can always complete quickly. |
| 160 // Note: This is a somewhat arbitrary test. |
| 161 const int kLoops = 10000; |
| 162 const int kMaxTime = 10; // Maximum acceptible milliseconds for test. |
| 163 |
| 164 typedef TimeTicks (*TestFunc)(); |
| 165 struct TestCase { |
| 166 TestFunc func; |
| 167 char *description; |
| 168 }; |
| 169 // Cheating a bit here: assumes sizeof(TimeTicks) == sizeof(Time) |
| 170 // in order to create a single test case list. |
| 171 COMPILE_ASSERT(sizeof(TimeTicks) == sizeof(Time), |
| 172 test_only_works_with_same_sizes); |
| 173 TestCase cases[] = { |
| 174 { reinterpret_cast<TestFunc>(Time::Now), "Time::Now" }, |
| 175 { TimeTicks::Now, "TimeTicks::Now" }, |
| 176 { TimeTicks::HighResNow, "TimeTicks::HighResNow" }, |
| 177 { NULL, "" } |
| 178 }; |
| 179 |
| 180 int test_case = 0; |
| 181 while (cases[test_case].func) { |
| 182 TimeTicks start = TimeTicks::HighResNow(); |
| 183 for (int index = 0; index < kLoops; index++) |
| 184 cases[test_case].func(); |
| 185 TimeTicks stop = TimeTicks::HighResNow(); |
| 186 EXPECT_LT((stop - start).InMilliseconds(), kMaxTime); |
| 187 printf("%s: %1.2fus per call\n", cases[test_case].description, |
| 188 (stop - start).InMillisecondsF() * 1000 / kLoops); |
| 189 test_case++; |
| 190 } |
| 191 } |
OLD | NEW |