ardour
timer_test.cc
Go to the documentation of this file.
1 #include "timer_test.h"
2 
3 #include <iostream>
4 #include <sstream>
5 #include <algorithm>
6 
7 #include "pbd/timer.h"
8 
9 #ifdef PLATFORM_WINDOWS
10 #include <windows.h>
11 #endif
12 
14 
15 using namespace std;
16 
17 #ifdef PLATFORM_WINDOWS
18 UINT&
19 min_timer_resolution ()
20 {
21  static UINT min_res_ms = 0;
22  return min_res_ms;
23 }
24 
25 bool
26 set_min_timer_resolution ()
27 {
28  TIMECAPS caps;
29 
30  if (timeGetDevCaps(&caps, sizeof(TIMECAPS)) != TIMERR_NOERROR) {
31  cerr << "Could not get timer device capabilities..." << endl;
32  } else {
33  if (timeBeginPeriod(caps.wPeriodMin) != TIMERR_NOERROR) {
34  cerr << "Could not set minimum timer resolution to: " << caps.wPeriodMin << "ms" << endl;
35  return false;
36  }
37  else {
38  cerr << "Multimedia timer resolution set to: " << caps.wPeriodMin << "ms" << endl;
39  min_timer_resolution() = caps.wPeriodMin;
40  return true;
41  }
42  }
43  return false;
44 }
45 
46 bool
47 reset_timer_resolution ()
48 {
49  if (min_timer_resolution()) {
50  if (timeEndPeriod(min_timer_resolution()) != TIMERR_NOERROR) {
51  cerr << "Could not reset timer resolution" << endl;
52  return false;
53  } else {
54  cerr << "Multimedia timer resolution reset" << endl;
55  return true;
56  }
57  }
58  return true;
59 }
60 
61 #endif
62 
63 void
64 TimerTest::simulate_load (const string& name, guint64 load_usecs)
65 {
66  PBD::Timing timing;
67  std::ostringstream oss;
68  oss << name << " Load.";
69 
70  guint64 i = 0;
71  do {
72  timing.update ();
73 
74  // totally arbitrary
75  if (i % 10000 == 0) {
76  oss << ".";
77  }
78 
79  ++i;
80  } while (timing.elapsed () < load_usecs);
81 
82  oss << "Expected = " << load_usecs;
83  oss << ", Elapsed = " << timing.elapsed ();
84  oss << endl;
85  //cerr << oss.str();
86 }
87 
88 void
90 {
91  cerr << endl;
92  cerr << "Timing Summary: " << m_current_test_name << endl;
93 
94  if (m_idle_timing_data.size()) {
95  cerr << "Idle Timing: " << m_idle_timing_data.summary();
96  }
97  if (m_fast_timing_data.size()) {
98  cerr << "Fast Timing: " << m_fast_timing_data.summary();
99  }
100  if (m_rapid1_timing_data.size()) {
101  cerr << "Rapid1 Timing: " << m_rapid1_timing_data.summary();
102  }
103  if (m_rapid2_timing_data.size()) {
104  cerr << "Rapid2 Timing: " << m_rapid2_timing_data.summary();
105  }
106  reset_timing ();
107 }
108 
109 bool
111 {
113  return true;
114 }
115 
116 void
118 {
119  m_fast_timing_data.add_interval ();
120  if (m_block_idle) {
121  // do nothing, handled in rapid timers
122  } else {
123  simulate_load ("Rapid1", 4000);
124  }
125 }
126 
127 bool
129 {
130  on_fast_timeout ();
131  return true;
132 }
133 
134 void
136 {
137  m_rapid1_timing_data.add_interval ();
138  if (m_block_idle) {
139  simulate_load ("Rapid1", rapid1_timer_usecs () * 0.5);
140  } else {
141  simulate_load ("Rapid1", 2000);
142  }
143 }
144 
145 bool
147 {
148  on_rapid1_timeout ();
149  return true;
150 }
151 
152 void
154 {
155  m_rapid2_timing_data.add_interval ();
156  if (m_block_idle) {
157  simulate_load ("Rapid2", rapid2_timer_usecs () * 0.5);
158  } else {
159  simulate_load ("Rapid2", 2000);
160  }
161 }
162 
163 bool
165 {
166  on_rapid2_timeout ();
167  return true;
168 }
169 
170 bool
172 {
173  m_idle_timing_data.add_interval ();
174  if (m_block_idle) {
175  simulate_load ("Idle", rapid2_timer_usecs ());
176  }
177  return true;
178 }
179 
180 bool
182 {
183  cerr << "Quit Handler" << endl;
184  m_main->quit ();
185  return false;
186 }
187 
188 void
190 {
191  m_idle_timing_data.reset ();
192  m_fast_timing_data.reset ();
193  m_rapid1_timing_data.reset ();
194  m_rapid2_timing_data.reset ();
195 }
196 
197 void
199 {
200  m_idle_timing_data.start_timing ();
201  m_fast_timing_data.start_timing ();
202  m_rapid1_timing_data.start_timing ();
203  m_rapid2_timing_data.start_timing ();
204 }
205 
206 gboolean
208 {
209  TimerTest *const tt = static_cast<TimerTest*>(data);
210  tt->on_second_timeout ();
211  return TRUE;
212 }
213 
214 gboolean
216 {
217  TimerTest *const tt = static_cast<TimerTest*>(data);
218  tt->on_fast_timeout ();
219  return TRUE;
220 }
221 
222 gboolean
224 {
225  TimerTest *const tt = static_cast<TimerTest*>(data);
226  tt->on_rapid1_timeout ();
227  return TRUE;
228 }
229 
230 gboolean
232 {
233  TimerTest *const tt = static_cast<TimerTest*>(data);
234  tt->on_rapid2_timeout ();
235  return TRUE;
236 }
237 
238 void
240 {
241  reset_timing ();
242  start_timing ();
243 
244  connect_quit_timeout ();
245 
246  m_main = Glib::MainLoop::create (m_context);
247  m_main->run ();
248 }
249 
250 void
252 {
253  m_current_test_name = "testGlibTimeoutSources";
254  _testGlibTimeoutSources ();
255 }
256 
257 void
259 {
260  m_context = Glib::MainContext::create ();
261 
262  GSource * second_timeout_source = g_timeout_source_new (second_timer_ms ());
263 
264  g_source_set_callback (second_timeout_source , &TimerTest::_second_timeout_handler, this, NULL);
265 
266  g_source_attach (second_timeout_source, m_context->gobj());
267 
268  if (m_connect_idle) {
269  connect_idle_handler ();
270  reset_timing_run_main ();
271  }
272 
273  GSource * fast_timeout_source = g_timeout_source_new (fast_timer_ms ());
274 
275  g_source_set_callback (fast_timeout_source , &TimerTest::_fast_timeout_handler, this, NULL);
276 
277  g_source_attach (fast_timeout_source, m_context->gobj());
278 
279  // now run with fast timeout
280  reset_timing_run_main ();
281 
282  GSource * rapid1_timeout_source = g_timeout_source_new (rapid1_timer_ms ());
283 
284  g_source_set_callback (rapid1_timeout_source , &TimerTest::_rapid1_timeout_handler, this, NULL);
285 
286  g_source_attach (rapid1_timeout_source, m_context->gobj());
287 
288  // now run with fast and rapid1 timeouts
289  reset_timing_run_main ();
290 
291  GSource * rapid2_timeout_source = g_timeout_source_new (rapid2_timer_ms ());
292 
293  g_source_set_callback (rapid2_timeout_source , &TimerTest::_rapid2_timeout_handler, this, NULL);
294 
295  g_source_attach (rapid2_timeout_source, m_context->gobj());
296 
297  // now run with fast, rapid1 and rapid2 timeouts
298  reset_timing_run_main ();
299 
300  // cleanup
301  g_source_destroy (second_timeout_source);
302  g_source_unref (second_timeout_source);
303 
304  g_source_destroy (fast_timeout_source);
305  g_source_unref (fast_timeout_source);
306 
307  g_source_destroy (rapid1_timeout_source);
308  g_source_unref (rapid1_timeout_source);
309 
310  g_source_destroy (rapid2_timeout_source);
311  g_source_unref (rapid2_timeout_source);
312 }
313 
314 void
316 {
317  m_current_test_name = "testGlibmmSignalTimeouts";
318  _testGlibmmSignalTimeouts ();
319 }
320 
321 void
323 {
324  m_context = Glib::MainContext::get_default ();
325 
326  Glib::signal_timeout().connect(sigc::mem_fun(*this, &TimerTest::on_second_timeout_glibmm), second_timer_ms());
327 
328  if (m_connect_idle) {
329  connect_idle_handler ();
330  reset_timing_run_main ();
331  }
332 
333  Glib::signal_timeout().connect(sigc::mem_fun(*this, &TimerTest::on_fast_timeout_glibmm), fast_timer_ms());
334 
335  reset_timing_run_main ();
336 
337  Glib::signal_timeout().connect(sigc::mem_fun(*this, &TimerTest::on_rapid1_timeout_glibmm), rapid1_timer_ms());
338 
339  reset_timing_run_main ();
340 
341  Glib::signal_timeout().connect(sigc::mem_fun(*this, &TimerTest::on_rapid2_timeout_glibmm), rapid2_timer_ms());
342 
343  reset_timing_run_main ();
344 }
345 
346 void
348 {
349  m_current_test_name = "testGlibmmTimeoutSources";
350  _testGlibmmTimeoutSources ();
351 }
352 
353 void
355 {
356  m_context = Glib::MainContext::create ();
357 
358  const Glib::RefPtr<Glib::TimeoutSource> second_source = Glib::TimeoutSource::create(second_timer_ms());
359  second_source->connect(sigc::mem_fun(*this, &TimerTest::on_second_timeout_glibmm));
360 
361  second_source->attach(m_context);
362 
363  if (m_connect_idle) {
364  connect_idle_handler ();
365  reset_timing_run_main ();
366  }
367 
368  const Glib::RefPtr<Glib::TimeoutSource> fast_source = Glib::TimeoutSource::create(fast_timer_ms());
369  fast_source->connect(sigc::mem_fun(*this, &TimerTest::on_fast_timeout_glibmm));
370 
371  fast_source->attach(m_context);
372 
373  reset_timing_run_main ();
374 
375  const Glib::RefPtr<Glib::TimeoutSource> rapid1_source = Glib::TimeoutSource::create(rapid1_timer_ms());
376  sigc::connection rapid1_connection = rapid1_source->connect(sigc::mem_fun(*this, &TimerTest::on_rapid1_timeout_glibmm));
377 
378  rapid1_source->attach(m_context);
379 
380  reset_timing_run_main ();
381 
382  const Glib::RefPtr<Glib::TimeoutSource> rapid2_source = Glib::TimeoutSource::create(rapid2_timer_ms());
383  sigc::connection rapid2_connection = rapid2_source->connect(sigc::mem_fun(*this, &TimerTest::on_rapid2_timeout_glibmm));
384 
385  rapid2_source->attach(m_context);
386 
387  reset_timing_run_main ();
388 }
389 
390 void
392 {
393  const Glib::RefPtr<Glib::IdleSource> idle_source = Glib::IdleSource::create();
394  idle_source->connect(sigc::mem_fun(*this, &TimerTest::on_idle_handler));
395 
396  idle_source->attach(m_context);
397 }
398 
399 void
401 {
402  const Glib::RefPtr<Glib::TimeoutSource> quit_source = Glib::TimeoutSource::create(test_length_ms());
403  quit_source->connect(sigc::mem_fun(*this, &TimerTest::on_quit_handler));
404 
405  quit_source->attach(m_context);
406 }
407 
408 void
410 {
411  m_current_test_name = "testTimers";
412  _testTimers ();
413 }
414 
415 void
417 {
418  m_context = Glib::MainContext::create ();
419 
420  PBD::StandardTimer second_timer (second_timer_ms (), m_context);
421  sigc::connection second_connection = second_timer.connect (sigc::mem_fun (this, &TimerTest::on_second_timeout));
422 
423  if (m_connect_idle) {
424  connect_idle_handler ();
425  // let the idle handler run as fast as it can
426  reset_timing_run_main();
427  }
428 
429  PBD::StandardTimer fast_timer (fast_timer_ms (), m_context);
430  sigc::connection fast_connection = fast_timer.connect (sigc::mem_fun (this, &TimerTest::on_fast_timeout));
431 
432  reset_timing_run_main();
433 
434  PBD::StandardTimer rapid1_timer (rapid1_timer_ms (), m_context);
435  sigc::connection rapid1_connection = rapid1_timer.connect (sigc::mem_fun (this, &TimerTest::on_rapid1_timeout));
436 
437  reset_timing_run_main();
438 
439  PBD::StandardTimer rapid2_timer (rapid2_timer_ms (), m_context);
440  sigc::connection rapid2_connection = rapid2_timer.connect (sigc::mem_fun (this, &TimerTest::on_rapid2_timeout));
441 
442  reset_timing_run_main();
443 }
444 
445 void
447 {
448  m_current_test_name = "testTimersIdleFrequency";
449  _testTimersIdleFrequency ();
450 }
451 
452 void
454 {
455  m_block_idle = false;
456  m_connect_idle = true;
457 
458  _testTimers ();
459 
460  m_block_idle = false;
461  m_connect_idle = false;
462 }
463 
464 void
466 {
467  m_current_test_name = "testTimersBlockIdle";
468  _testTimersBlockIdle ();
469 }
470 
471 void
473 {
474  m_block_idle = true;
475  m_connect_idle = true;
476 
477  _testTimers ();
478 
479  m_block_idle = false;
480  m_connect_idle = false;
481 }
482 
483 #ifdef PLATFORM_WINDOWS
484 void
485 TimerTest::testGlibTimeoutSourcesHR ()
486 {
487  CPPUNIT_ASSERT(set_min_timer_resolution());
488 
489  m_current_test_name = "testGlibTimeoutSourcesHR";
490  _testGlibTimeoutSources ();
491 
492  CPPUNIT_ASSERT(reset_timer_resolution());
493 }
494 
495 void
496 TimerTest::testGlibmmSignalTimeoutsHR ()
497 {
498  CPPUNIT_ASSERT(set_min_timer_resolution());
499 
500  m_current_test_name = "testGlibmmSignalTimeoutsHR";
501  _testGlibmmSignalTimeouts ();
502 
503  CPPUNIT_ASSERT(reset_timer_resolution());
504 }
505 
506 void
507 TimerTest::testGlibmmTimeoutSourcesHR ()
508 {
509  CPPUNIT_ASSERT(set_min_timer_resolution());
510 
511  m_current_test_name = "testGlibmmTimeoutSourcesHR";
512  _testGlibmmTimeoutSources ();
513 
514  CPPUNIT_ASSERT(reset_timer_resolution());
515 }
516 
517 void
518 TimerTest::testTimersHR ()
519 {
520  CPPUNIT_ASSERT(set_min_timer_resolution());
521 
522  m_current_test_name = "testTimersHR";
523  _testTimers ();
524 
525  CPPUNIT_ASSERT(reset_timer_resolution());
526 }
527 
528 void
529 TimerTest::testTimersIdleFrequencyHR ()
530 {
531  CPPUNIT_ASSERT(set_min_timer_resolution());
532 
533  m_current_test_name = "testTimersIdleFrequencyHR";
534  _testTimersIdleFrequency ();
535 
536  CPPUNIT_ASSERT(reset_timer_resolution());
537 }
538 
539 void
540 TimerTest::testTimersBlockIdleHR ()
541 {
542  CPPUNIT_ASSERT(set_min_timer_resolution());
543 
544  m_current_test_name = "testTimersIdleFrequencyHR";
545  _testTimersBlockIdle ();
546 
547  CPPUNIT_ASSERT(reset_timer_resolution());
548 }
549 
550 #endif
static void simulate_load(const std::string &name, guint64 time_usecs)
Definition: timer_test.cc:64
bool on_quit_handler()
Definition: timer_test.cc:181
bool on_idle_handler()
Definition: timer_test.cc:171
void testGlibmmSignalTimeouts()
Definition: timer_test.cc:315
void testTimersIdleFrequency()
Definition: timer_test.cc:446
sigc::connection connect(const sigc::slot< void > &slot)
Definition: timer.cc:108
void testGlibmmTimeoutSources()
Definition: timer_test.cc:347
void on_fast_timeout()
Definition: timer_test.cc:117
Definition: Beats.hpp:239
void on_rapid1_timeout()
Definition: timer_test.cc:135
void testGlibTimeoutSources()
Definition: timer_test.cc:251
void connect_quit_timeout()
Definition: timer_test.cc:400
static gboolean _fast_timeout_handler(void *)
Definition: timer_test.cc:215
bool on_rapid1_timeout_glibmm()
Definition: timer_test.cc:146
void start_timing()
Definition: timer_test.cc:198
void testTimersBlockIdle()
Definition: timer_test.cc:465
void reset_timing()
Definition: timer_test.cc:189
static gboolean _second_timeout_handler(void *)
Definition: timer_test.cc:207
void connect_idle_handler()
Definition: timer_test.cc:391
CPPUNIT_TEST_SUITE_REGISTRATION(TimerTest)
static gboolean _rapid1_timeout_handler(void *)
Definition: timer_test.cc:223
void on_second_timeout()
Definition: timer_test.cc:89
static gboolean _rapid2_timeout_handler(void *)
Definition: timer_test.cc:231
void _testGlibmmTimeoutSources()
Definition: timer_test.cc:354
const char * name
bool on_fast_timeout_glibmm()
Definition: timer_test.cc:128
uint64_t elapsed() const
Elapsed time in microseconds.
Definition: timing.h:97
void _testTimersBlockIdle()
Definition: timer_test.cc:472
void _testGlibTimeoutSources()
Definition: timer_test.cc:258
void _testTimers()
Definition: timer_test.cc:416
void reset_timing_run_main()
Definition: timer_test.cc:239
bool on_second_timeout_glibmm()
Definition: timer_test.cc:110
bool on_rapid2_timeout_glibmm()
Definition: timer_test.cc:164
void _testTimersIdleFrequency()
Definition: timer_test.cc:453
void _testGlibmmSignalTimeouts()
Definition: timer_test.cc:322
void testTimers()
Definition: timer_test.cc:409
void update()
Definition: timing.h:77
void on_rapid2_timeout()
Definition: timer_test.cc:153