1 #include <cppunit/TestFixture.h>
2 #include <cppunit/extensions/HelperMacros.h>
4 #include "glibmm/main.h"
6 #include "pbd/timing.h"
9 * The main point of this test is to the compare the different
10 * ways of setting a timeout with glib and glibmm and the
11 * PBD::Timers class and then to test them all again with
12 * the maximum multimedia timer resolution(1ms) set with
13 * timeBeginPeriod on Windows.
15 * The test demonstrates that when using Glibmm TimeoutSources
16 * the frequency of the timers is different that using Glib based
17 * timeouts. In Ardour that resulted in a noticable increase in
18 * CPU Usage, but behaviour may vary.
20 * The other thing being tested is what effect adding two short
21 * timeouts(<40ms) to a glib context has on the idle timeout on
24 * Glib Timeout sources run at a higher priority than the idle
25 * handler, so the more work performed in the timeout handlers
26 * the less frequent the idle handler will run until doesn't get
27 * scheduled at all. The consequence of this is blocking the UI.
29 * Similarily because timeout sources and UI updates/rendering
30 * occur in the same context in Gtk the length of expose/draw
31 * operations will affect the accuracy of the timeouts.
33 class TimerTest : public CppUnit::TestFixture
35 CPPUNIT_TEST_SUITE (TimerTest);
36 CPPUNIT_TEST (testGlibTimeoutSources);
37 CPPUNIT_TEST (testGlibmmSignalTimeouts);
38 CPPUNIT_TEST (testGlibmmTimeoutSources);
39 CPPUNIT_TEST (testTimers);
40 CPPUNIT_TEST (testTimersIdleFrequency);
41 CPPUNIT_TEST (testTimersBlockIdle);
42 #ifdef PLATFORM_WINDOWS
43 CPPUNIT_TEST (testGlibTimeoutSourcesHR);
44 CPPUNIT_TEST (testGlibmmSignalTimeoutsHR);
45 CPPUNIT_TEST (testGlibmmTimeoutSourcesHR);
46 CPPUNIT_TEST (testTimersHR);
47 CPPUNIT_TEST (testTimersIdleFrequencyHR);
48 CPPUNIT_TEST (testTimersBlockIdleHR);
50 CPPUNIT_TEST_SUITE_END ();
55 : m_connect_idle(false)
59 void _testGlibTimeoutSources ();
60 void _testGlibmmSignalTimeouts ();
61 void _testGlibmmTimeoutSources ();
63 void _testTimersIdleFrequency ();
64 void _testTimersBlockIdle ();
66 void testGlibTimeoutSources ();
67 void testGlibmmSignalTimeouts ();
68 void testGlibmmTimeoutSources ();
70 void testTimersIdleFrequency ();
71 void testTimersBlockIdle ();
73 #ifdef PLATFORM_WINDOWS
74 void testGlibTimeoutSourcesHR ();
75 void testGlibmmSignalTimeoutsHR ();
76 void testGlibmmTimeoutSourcesHR ();
78 void testTimersIdleFrequencyHR ();
79 void testTimersBlockIdleHR ();
84 static guint64 second_timer_usecs ()
87 static guint64 fast_timer_usecs ()
90 static guint64 rapid1_timer_usecs ()
93 static guint64 rapid2_timer_usecs ()
96 static guint64 second_timer_ms ()
97 { return second_timer_usecs () / 1000; }
99 static guint64 fast_timer_ms ()
100 { return fast_timer_usecs () / 1000; }
102 static guint64 rapid1_timer_ms ()
103 { return rapid1_timer_usecs () / 1000; }
105 static guint64 rapid2_timer_ms ()
106 { return rapid2_timer_usecs () / 1000; }
108 static guint64 test_length_ms ()
109 { return 10 * 1000; }
111 std::string m_current_test_name;
116 bool on_idle_handler ();
117 bool on_quit_handler ();
119 void on_second_timeout ();
120 void on_fast_timeout ();
121 void on_rapid1_timeout ();
122 void on_rapid2_timeout ();
124 bool on_second_timeout_glibmm ();
125 bool on_fast_timeout_glibmm ();
126 bool on_rapid1_timeout_glibmm ();
127 bool on_rapid2_timeout_glibmm ();
129 static gboolean _second_timeout_handler (void*);
130 static gboolean _fast_timeout_handler (void*);
131 static gboolean _rapid1_timeout_handler (void*);
132 static gboolean _rapid2_timeout_handler (void*);
134 void start_timing ();
135 void reset_timing ();
137 void reset_timing_run_main ();
140 simulate_load (const std::string& name, guint64 time_usecs);
141 Glib::RefPtr<Glib::MainLoop> m_main;
142 Glib::RefPtr<Glib::MainContext> m_context;
144 void connect_idle_handler ();
145 void connect_quit_timeout ();
147 PBD::TimingData m_idle_timing_data;
148 PBD::TimingData m_second_timing_data;
149 PBD::TimingData m_fast_timing_data;
150 PBD::TimingData m_rapid1_timing_data;
151 PBD::TimingData m_rapid2_timing_data;