13
0
livetrax/libs/pbd/test/windows_timer_utils_test.cc
Tim Mayberry 2e9e8d3b33 Fix windows test to also pass under wine
It looks as if the default timer resolution for applications running under wine
is different than Windows so just test that the minimum timer resolution is
below a certain amount rather than checking before and after calling
timeBeginPeriod
2015-09-19 10:59:39 +10:00

166 lines
4.9 KiB
C++

#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 ()
{
// 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);
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, elapsed);
max_elapsed = std::max (max_elapsed, elapsed);
total_elapsed += elapsed;
last_time_ms = current_time_ms;
}
// the rounding here doesn't matter, we aren't interested in
// accurate measurements
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
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 the avg granularity is the same as miniumum resolution
CPPUNIT_ASSERT (avg_min_res_tgt_elapsed == 1);
uint32_t avg_min_res_sleep_elapsed = 0;
test_sleep_granularity ("Minimum Timer Resolution", avg_min_res_sleep_elapsed);
// In a heavily loaded system and without running this test with raised
// scheduling priority we can't assume that the sleep granularity is the
// same as the minimum timer resolution so give it 1ms of slack, if it is
// greater than that then there likely is a problem that needs
// investigating.
CPPUNIT_ASSERT (avg_min_res_sleep_elapsed <= 2);
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.
}