diff --git a/libs/pbd/pbd/windows_timer_utils.h b/libs/pbd/pbd/windows_timer_utils.h index 72d3cc5431..4ebeacd6eb 100644 --- a/libs/pbd/pbd/windows_timer_utils.h +++ b/libs/pbd/pbd/windows_timer_utils.h @@ -61,8 +61,11 @@ namespace QPC { /** * @return true if QueryPerformanceCounter is usable as a timer source + * This should always return true for systems > XP as those versions of windows + * have there own tests to check timer validity and will select an appropriate + * timer source. */ -bool get_timer_valid (); +bool check_timer_valid (); /** * @return the value of the performance counter converted to microseconds diff --git a/libs/pbd/test/windows_timer_utils_test.cc b/libs/pbd/test/windows_timer_utils_test.cc index fe5e1a24df..1566f37d96 100644 --- a/libs/pbd/test/windows_timer_utils_test.cc +++ b/libs/pbd/test/windows_timer_utils_test.cc @@ -13,7 +13,8 @@ CPPUNIT_TEST_SUITE_REGISTRATION (WindowsTimerUtilsTest); void WindowsTimerUtilsTest::testQPC () { - CPPUNIT_ASSERT (PBD::QPC::get_timer_valid()); + // performs basically the same test + CPPUNIT_ASSERT (PBD::QPC::check_timer_valid()); int64_t last_timer_val = PBD::QPC::get_microseconds (); CPPUNIT_ASSERT (last_timer_val >= 0); diff --git a/libs/pbd/windows_timer_utils.cc b/libs/pbd/windows_timer_utils.cc index d95a69e0c7..ee7cd962c5 100644 --- a/libs/pbd/windows_timer_utils.cc +++ b/libs/pbd/windows_timer_utils.cc @@ -136,16 +136,35 @@ qpc_frequency_cached () return frequency; } +bool +test_qpc_validity () +{ + int64_t last_timer_val = PBD::QPC::get_microseconds (); + if (last_timer_val < 0) return false; + + for (int i = 0; i < 100000; ++i) { + int64_t timer_val = PBD::QPC::get_microseconds (); + if (timer_val < 0) return false; + // try and test for non-syncronized TSC(AMD K8/etc) + if (timer_val < last_timer_val) return false; + last_timer_val = timer_val; + } + return true; +} + } // anon namespace namespace QPC { bool -get_timer_valid () +check_timer_valid () { // setup caching the timer frequency qpc_frequency_cached (); - return qpc_frequency_success (); + if (!qpc_frequency_success ()) { + return false; + } + return test_qpc_validity (); } int64_t