summaryrefslogtreecommitdiffstats
path: root/base/time_unittest_win.cc
diff options
context:
space:
mode:
authormbelshe@google.com <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-26 03:00:00 +0000
committermbelshe@google.com <mbelshe@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-09-26 03:00:00 +0000
commitde592d31b3e82b1ff938c46f3db8cb06a716062e (patch)
tree32af531b478fabff890ca7b7dee71ffccf744048 /base/time_unittest_win.cc
parentf5e3da4d564980a048f375cf1a824a01df03382a (diff)
downloadchromium_src-de592d31b3e82b1ff938c46f3db8cb06a716062e.zip
chromium_src-de592d31b3e82b1ff938c46f3db8cb06a716062e.tar.gz
chromium_src-de592d31b3e82b1ff938c46f3db8cb06a716062e.tar.bz2
Change to Hi Res timers on Windows.
There are two parts of this: 1) TimeTicks:Now() Don't call timeBeginPeriod() in all cases. Use the new SystemMonitor class to watch battery on/off transitions and use the timeBeginPeriod() only when we're using the battery. 2) TimeTicks::UnreliableHiResNow() Change this function from "UnreliableHiResNow()" to "HiResNow()". We still use QPC, but we detect if we're on AMD Athlon XP machines which fail on QPC. For those systems, we fall back to TimeTicks::Now(). Updated tests to detect hardware specifics of timers. Output of the test will contain lines such as these: [ RUN ] TimeTicks.SubMillisecondTimers Min timer is: 1us [ OK ] TimeTicks.SubMillisecondTimers [ RUN ] TimeTicks.TimeGetTimeCaps timeGetTime range is 1 to 1000000ms [ OK ] TimeTicks.TimeGetTimeCaps [ RUN ] TimeTicks.QueryPerformanceFrequency QueryPerformanceFrequency is 2394.18MHz [ OK ] TimeTicks.QueryPerformanceFrequency [ RUN ] TimeTicks.TimerPerformance Time::Now: 0.11us per call TimeTicks::Now: 0.09us per call TimeTicks::HighResNow: 0.26us per call [ OK ] TimeTicks.TimerPerformance Review URL: http://codereview.chromium.org/4092 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@2625 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/time_unittest_win.cc')
-rw-r--r--base/time_unittest_win.cc92
1 files changed, 91 insertions, 1 deletions
diff --git a/base/time_unittest_win.cc b/base/time_unittest_win.cc
index 87cf698..4a7120e 100644
--- a/base/time_unittest_win.cc
+++ b/base/time_unittest_win.cc
@@ -3,6 +3,7 @@
// found in the LICENSE file.
#include <windows.h>
+#include <mmsystem.h>
#include <process.h>
#include "base/time.h"
@@ -44,7 +45,9 @@ unsigned __stdcall RolloverTestThreadMain(void* param) {
for (int index = 0; index < counter; index++) {
TimeTicks now = TimeTicks::Now();
int64 milliseconds = (now - last).InMilliseconds();
- EXPECT_GT(milliseconds, 0);
+ // This is a tight loop; we could have looped faster than our
+ // measurements, so the time might be 0 millis.
+ EXPECT_GE(milliseconds, 0);
EXPECT_LT(milliseconds, 250);
last = now;
}
@@ -99,3 +102,90 @@ TEST(TimeTicks, WinRollover) {
MockTimeTicks::UninstallTicker();
}
}
+
+TEST(TimeTicks, SubMillisecondTimers) {
+ // Loop for a bit getting timers quickly. We want to
+ // see at least one case where we get a new sample in
+ // less than one millisecond.
+ bool saw_submillisecond_timer = false;
+ int64 min_timer = 1000;
+ TimeTicks last_time = TimeTicks::HighResNow();
+ for (int index = 0; index < 1000; index++) {
+ TimeTicks now = TimeTicks::HighResNow();
+ TimeDelta delta = now - last_time;
+ if (delta.InMicroseconds() > 0 &&
+ delta.InMicroseconds() < 1000) {
+ if (min_timer > delta.InMicroseconds())
+ min_timer = delta.InMicroseconds();
+ saw_submillisecond_timer = true;
+ }
+ last_time = now;
+ }
+ EXPECT_TRUE(saw_submillisecond_timer);
+ printf("Min timer is: %dus\n", min_timer);
+}
+
+TEST(TimeTicks, TimeGetTimeCaps) {
+ // Test some basic assumptions that we expect about how timeGetDevCaps works.
+
+ TIMECAPS caps;
+ MMRESULT status = timeGetDevCaps(&caps, sizeof(caps));
+ EXPECT_EQ(TIMERR_NOERROR, status);
+ if (status != TIMERR_NOERROR) {
+ printf("Could not get timeGetDevCaps\n");
+ return;
+ }
+
+ EXPECT_GE(static_cast<int>(caps.wPeriodMin), 1);
+ EXPECT_GT(static_cast<int>(caps.wPeriodMax), 1);
+ EXPECT_GE(static_cast<int>(caps.wPeriodMin), 1);
+ EXPECT_GT(static_cast<int>(caps.wPeriodMax), 1);
+ printf("timeGetTime range is %d to %dms\n", caps.wPeriodMin,
+ caps.wPeriodMax);
+}
+
+TEST(TimeTicks, QueryPerformanceFrequency) {
+ // Test some basic assumptions that we expect about QPC.
+
+ LARGE_INTEGER frequency;
+ BOOL rv = QueryPerformanceFrequency(&frequency);
+ EXPECT_EQ(TRUE, rv);
+ EXPECT_GT(frequency.QuadPart, 1000000); // Expect at least 1MHz
+ printf("QueryPerformanceFrequency is %5.2fMHz\n",
+ frequency.QuadPart / 1000000.0);
+}
+
+TEST(TimeTicks, TimerPerformance) {
+ // Verify that various timer mechanisms can always complete quickly.
+ // Note: This is a somewhat arbitrary test.
+ const int kLoops = 10000;
+ const int kMaxTime = 10; // Maximum acceptible milliseconds for test.
+
+ typedef TimeTicks (*TestFunc)();
+ struct TestCase {
+ TestFunc func;
+ char *description;
+ };
+ // Cheating a bit here: assumes sizeof(TimeTicks) == sizeof(Time)
+ // in order to create a single test case list.
+ COMPILE_ASSERT(sizeof(TimeTicks) == sizeof(Time),
+ test_only_works_with_same_sizes);
+ TestCase cases[] = {
+ { reinterpret_cast<TestFunc>(Time::Now), "Time::Now" },
+ { TimeTicks::Now, "TimeTicks::Now" },
+ { TimeTicks::HighResNow, "TimeTicks::HighResNow" },
+ { NULL, "" }
+ };
+
+ int test_case = 0;
+ while (cases[test_case].func) {
+ TimeTicks start = TimeTicks::HighResNow();
+ for (int index = 0; index < kLoops; index++)
+ cases[test_case].func();
+ TimeTicks stop = TimeTicks::HighResNow();
+ EXPECT_LT((stop - start).InMilliseconds(), kMaxTime);
+ printf("%s: %1.2fus per call\n", cases[test_case].description,
+ (stop - start).InMillisecondsF() * 1000 / kLoops);
+ test_case++;
+ }
+}