diff options
author | deanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-02 08:28:37 +0000 |
---|---|---|
committer | deanm@google.com <deanm@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-09-02 08:28:37 +0000 |
commit | 5f6eee53a4ba6995b68a8ec6f22d3281529060c8 (patch) | |
tree | 1464c7ca7fdaaa3b7f387da90db9667988c1f25d /base/time_unittest_win.cc | |
parent | 38f70a3e2ade7049c09831ed8f5b8ea90d9e68d6 (diff) | |
download | chromium_src-5f6eee53a4ba6995b68a8ec6f22d3281529060c8.zip chromium_src-5f6eee53a4ba6995b68a8ec6f22d3281529060c8.tar.gz chromium_src-5f6eee53a4ba6995b68a8ec6f22d3281529060c8.tar.bz2 |
Cleanup some Windows TimeTicks functions. Move TickTicks::Now and TicksTicks::UnreliableHighResNow to Singletons, which cleans up the code and removes some possible unsafe cross-thread access.
Move the Windows-specific rollover tests to time_unittests_win.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@1633 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/time_unittest_win.cc')
-rw-r--r-- | base/time_unittest_win.cc | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/base/time_unittest_win.cc b/base/time_unittest_win.cc new file mode 100644 index 0000000..5b29db2 --- /dev/null +++ b/base/time_unittest_win.cc @@ -0,0 +1,102 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <windows.h> +#include <process.h> + +#include "base/time.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +class MockTimeTicks : public TimeTicks { + public: + static int Ticker() { + return static_cast<int>(InterlockedIncrement(&ticker_)); + } + + static void InstallTicker() { + old_tick_function_ = tick_function_; + tick_function_ = reinterpret_cast<TickFunction>(&Ticker); + ticker_ = -5; + } + + static void UninstallTicker() { + tick_function_ = old_tick_function_; + } + + private: + static volatile LONG ticker_; + static TickFunction old_tick_function_; +}; + +volatile LONG MockTimeTicks::ticker_; +MockTimeTicks::TickFunction MockTimeTicks::old_tick_function_; + +HANDLE g_rollover_test_start; + +unsigned __stdcall RolloverTestThreadMain(void* param) { + int64 counter = reinterpret_cast<int64>(param); + DWORD rv = WaitForSingleObject(g_rollover_test_start, INFINITE); + EXPECT_EQ(rv, WAIT_OBJECT_0); + + TimeTicks last = TimeTicks::Now(); + for (int index = 0; index < counter; index++) { + TimeTicks now = TimeTicks::Now(); + int64 milliseconds = (now - last).InMilliseconds(); + EXPECT_GT(milliseconds, 0); + EXPECT_LT(milliseconds, 250); + last = now; + } + return 0; +} + +} // namespace + +TEST(TimeTicks, WinRollover) { + // The internal counter rolls over at ~49days. We'll use a mock + // timer to test this case. + // Basic test algorithm: + // 1) Set clock to rollover - N + // 2) Create N threads + // 3) Start the threads + // 4) Each thread loops through TimeTicks() N times + // 5) Each thread verifies integrity of result. + + const int kThreads = 8; + // Use int64 so we can cast into a void* without a compiler warning. + const int64 kChecks = 10; + + // It takes a lot of iterations to reproduce the bug! + // (See bug 1081395) + for (int loop = 0; loop < 4096; loop++) { + // Setup + MockTimeTicks::InstallTicker(); + g_rollover_test_start = CreateEvent(0, TRUE, FALSE, 0); + HANDLE threads[kThreads]; + + for (int index = 0; index < kThreads; index++) { + void* argument = reinterpret_cast<void*>(kChecks); + unsigned thread_id; + threads[index] = reinterpret_cast<HANDLE>( + _beginthreadex(NULL, 0, RolloverTestThreadMain, argument, 0, + &thread_id)); + EXPECT_NE((HANDLE)NULL, threads[index]); + } + + // Start! + SetEvent(g_rollover_test_start); + + // Wait for threads to finish + for (int index = 0; index < kThreads; index++) { + DWORD rv = WaitForSingleObject(threads[index], INFINITE); + EXPECT_EQ(rv, WAIT_OBJECT_0); + } + + CloseHandle(g_rollover_test_start); + + // Teardown + MockTimeTicks::UninstallTicker(); + } +} |