summaryrefslogtreecommitdiff
path: root/libs/pbd
diff options
context:
space:
mode:
authorTim Mayberry <mojofunk@gmail.com>2015-09-14 10:33:48 +1000
committerTim Mayberry <mojofunk@gmail.com>2015-09-16 11:22:16 +1000
commitcd05d46c007583a27be23e2ae8cedc5ea9746373 (patch)
tree67cc6ad1bcb92df231a6fcfd67545699a0b80126 /libs/pbd
parenta88b2da6a90b1d6f3004333a89761d312b02cf37 (diff)
Add windows specific test for pbd/windows_timer_utils.h API
Diffstat (limited to 'libs/pbd')
-rw-r--r--libs/pbd/test/windows_timer_utils_test.cc163
-rw-r--r--libs/pbd/test/windows_timer_utils_test.h15
-rw-r--r--libs/pbd/wscript2
3 files changed, 180 insertions, 0 deletions
diff --git a/libs/pbd/test/windows_timer_utils_test.cc b/libs/pbd/test/windows_timer_utils_test.cc
new file mode 100644
index 0000000000..fe5e1a24df
--- /dev/null
+++ b/libs/pbd/test/windows_timer_utils_test.cc
@@ -0,0 +1,163 @@
+#include "windows_timer_utils_test.h"
+
+#include "pbd/windows_timer_utils.h"
+
+#include <windows.h>
+
+#include <iostream>
+
+using namespace std;
+
+CPPUNIT_TEST_SUITE_REGISTRATION (WindowsTimerUtilsTest);
+
+void
+WindowsTimerUtilsTest::testQPC ()
+{
+ CPPUNIT_ASSERT (PBD::QPC::get_timer_valid());
+
+ int64_t last_timer_val = PBD::QPC::get_microseconds ();
+ CPPUNIT_ASSERT (last_timer_val >= 0);
+
+ int64_t min_interval = 1000000;
+ int64_t max_interval = 0;
+
+ for (int i = 0; i < 10000; ++i) {
+ int64_t timer_val = PBD::QPC::get_microseconds ();
+ CPPUNIT_ASSERT (timer_val >= 0);
+ // try and test for non-syncronized TSC(AMD K8/etc)
+ CPPUNIT_ASSERT (timer_val >= last_timer_val);
+ min_interval = std::min (min_interval, timer_val - last_timer_val);
+ // We may get swapped out so a max interval is not so informative
+ max_interval = std::max (max_interval, timer_val - last_timer_val);
+ last_timer_val = timer_val;
+ }
+
+ cout << endl;
+ cout << "Min QPC interval = " << min_interval << endl;
+ cout << "Max QPC interval = " << max_interval << endl;
+}
+
+namespace {
+
+void get_tgt_granularity(uint32_t& min_elapsed,
+ uint32_t& max_elapsed,
+ uint32_t& avg_elapsed)
+{
+ min_elapsed = 1000;
+ max_elapsed = 0;
+ uint32_t count = 64;
+ uint32_t total_elapsed = 0;
+
+ uint32_t last_time_ms = timeGetTime();
+ for (uint32_t i = 0; i < count;) {
+ uint32_t current_time_ms = timeGetTime();
+ if (current_time_ms == last_time_ms) continue;
+ uint32_t elapsed = current_time_ms - last_time_ms;
+ cout << "TGT elapsed = " << elapsed << endl;
+ min_elapsed = std::min (min_elapsed, elapsed);
+ max_elapsed = std::max (max_elapsed, elapsed);
+ total_elapsed += elapsed;
+ last_time_ms = current_time_ms;
+ ++i;
+ }
+ avg_elapsed = total_elapsed / count;
+}
+
+void get_sleep_granularity(uint32_t& min_elapsed,
+ uint32_t& max_elapsed,
+ uint32_t& avg_elapsed)
+{
+ min_elapsed = 1000;
+ max_elapsed = 0;
+ uint32_t count = 64;
+ uint32_t total_elapsed = 0;
+
+ uint32_t last_time_ms = timeGetTime();
+ for (uint32_t i = 0; i < count; ++i) {
+ Sleep(1);
+ uint32_t current_time_ms = timeGetTime();
+ uint32_t elapsed = current_time_ms - last_time_ms;
+ cout << "Sleep elapsed = " << elapsed << endl;
+ min_elapsed = std::min (min_elapsed, current_time_ms - last_time_ms);
+ max_elapsed = std::max (max_elapsed, current_time_ms - last_time_ms);
+ total_elapsed += elapsed;
+ last_time_ms = current_time_ms;
+ }
+ avg_elapsed = total_elapsed / count;
+}
+
+void
+test_tgt_granularity (const std::string& test_name, uint32_t& tgt_avg_elapsed)
+{
+ uint32_t tgt_min_elapsed = 0;
+ uint32_t tgt_max_elapsed = 0;
+
+ get_tgt_granularity(
+ tgt_min_elapsed, tgt_max_elapsed, tgt_avg_elapsed);
+
+ cout << endl;
+ cout << "TGT " << test_name << " min elapsed = " << tgt_min_elapsed << endl;
+ cout << "TGT " << test_name << " max elapsed = " << tgt_max_elapsed << endl;
+ cout << "TGT " << test_name << " avg elapsed = " << tgt_avg_elapsed << endl;
+}
+
+void
+test_sleep_granularity (const std::string& test_name, uint32_t& sleep_avg_elapsed)
+{
+ uint32_t sleep_min_elapsed = 0;
+ uint32_t sleep_max_elapsed = 0;
+
+ get_sleep_granularity(
+ sleep_min_elapsed, sleep_max_elapsed, sleep_avg_elapsed);
+
+ cout << endl;
+ cout << "Sleep " << test_name << " min elapsed = " << sleep_min_elapsed << endl;
+ cout << "Sleep " << test_name << " max elapsed = " << sleep_max_elapsed << endl;
+ cout << "Sleep " << test_name << " avg elapsed = " << sleep_avg_elapsed << endl;
+}
+
+} // namespace
+
+/**
+ * This test will not succeed if the current system wide timer resolution is
+ * already at the minimum but in most cases it won't be and it will test
+ * whether setting the minimum timer resolution is successful.
+ */
+void
+WindowsTimerUtilsTest::testMMTimers ()
+{
+ uint32_t min_timer_res = 0;
+ CPPUNIT_ASSERT (PBD::MMTIMERS::get_min_resolution (min_timer_res));
+ CPPUNIT_ASSERT (min_timer_res == 1);
+
+ uint32_t avg_orig_res_tgt_elapsed = 0;
+
+ test_tgt_granularity ("Original Timer Resolution", avg_orig_res_tgt_elapsed);
+
+ uint32_t avg_orig_res_sleep_elapsed = 0;
+
+ test_sleep_granularity ("Original Timer Resolution", avg_orig_res_sleep_elapsed);
+
+ // set the min timer resolution
+ CPPUNIT_ASSERT (PBD::MMTIMERS::set_min_resolution ());
+
+ uint32_t avg_min_res_tgt_elapsed = 0;
+
+ test_tgt_granularity ("Minimum Timer Resolution", avg_min_res_tgt_elapsed);
+
+ // test that it is less than original granularity
+ CPPUNIT_ASSERT (avg_min_res_tgt_elapsed < avg_orig_res_tgt_elapsed);
+
+ uint32_t avg_min_res_sleep_elapsed = 0;
+
+ test_sleep_granularity ("Minimum Timer Resolution", avg_min_res_sleep_elapsed);
+
+ // test that it is less than original granularity
+ CPPUNIT_ASSERT (avg_min_res_sleep_elapsed < avg_orig_res_sleep_elapsed);
+
+ CPPUNIT_ASSERT (PBD::MMTIMERS::reset_resolution());
+
+ // You can't test setting the max timer resolution because AFAIR Windows
+ // will use the minimum requested resolution of all the applications on the
+ // system.
+}
diff --git a/libs/pbd/test/windows_timer_utils_test.h b/libs/pbd/test/windows_timer_utils_test.h
new file mode 100644
index 0000000000..11ab4a45b4
--- /dev/null
+++ b/libs/pbd/test/windows_timer_utils_test.h
@@ -0,0 +1,15 @@
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+
+class WindowsTimerUtilsTest : public CppUnit::TestFixture
+{
+ CPPUNIT_TEST_SUITE (WindowsTimerUtilsTest);
+ CPPUNIT_TEST (testQPC);
+ CPPUNIT_TEST (testMMTimers);
+ CPPUNIT_TEST_SUITE_END ();
+
+public:
+ void testQPC ();
+ void testMMTimers ();
+
+};
diff --git a/libs/pbd/wscript b/libs/pbd/wscript
index ed79593dd0..2d832669d1 100644
--- a/libs/pbd/wscript
+++ b/libs/pbd/wscript
@@ -165,6 +165,8 @@ def build(bld):
test/xml_test.cc
test/test_common.cc
'''.split()
+ if bld.env['build_target'] == 'mingw':
+ testobj.source += [ 'test/windows_timer_utils_test.cc' ]
testobj.target = 'run-tests'
testobj.includes = obj.includes + ['test', '../pbd']
testobj.uselib = 'CPPUNIT XML SNDFILE'