supernova: jack backend - improve xrun handling
[supercollider.git] / testsuite / supernova / server_dsp_thread_test.cpp
blobb4a27ac10245bbc9a2a7d05d92cc19c460e28d4d
1 #include <boost/test/unit_test.hpp>
3 #include <vector>
5 #include "dsp_thread_queue/dsp_thread.hpp"
6 #include "server/memory_pool.hpp"
8 namespace
11 volatile int gint;
13 struct dummy_runnable
15 dummy_runnable(void):
16 i(0)
19 void operator()(uint dummy)
21 ++i;
23 for (int j = 0; j != 1000; ++j)
25 int l = gint;
26 l += 1;
27 gint = l;
31 int i;
34 dummy_runnable dummy;
37 template <typename Alloc>
38 void run_test_1(void)
40 nova::dsp_threads<dummy_runnable, nova::nop_thread_init, Alloc> t(1);
43 BOOST_AUTO_TEST_CASE( dsp_thread_test_1 )
45 nova::rt_pool.init(1024*1024*128);
46 run_test_1<std::allocator<void*> >();
47 run_test_1<nova::rt_pool_allocator<void*> >();
50 template <typename Alloc>
51 void run_test_2(void)
53 nova::dsp_threads<dummy_runnable, nova::nop_thread_init, Alloc> t(5);
54 t.start_threads();
55 t.terminate_threads();
59 BOOST_AUTO_TEST_CASE( dsp_thread_test_2 )
61 run_test_2<std::allocator<void*> >();
62 run_test_2<nova::rt_pool_allocator<void*> >();
65 template <typename Alloc>
66 void run_test_3(void)
68 nova::dsp_threads<dummy_runnable, nova::nop_thread_init, Alloc> t(2);
69 t.start_threads();
70 t.run();
71 t.terminate_threads();
74 BOOST_AUTO_TEST_CASE( dsp_thread_test_3 )
76 run_test_3<std::allocator<void*> >();
77 run_test_3<nova::rt_pool_allocator<void*> >();
80 #ifdef __GXX_EXPERIMENTAL_CXX0X__
81 #define auto_ptr unique_ptr
82 #define MOVE(X) std::move(X)
83 #else
84 #define MOVE(X) X
85 #endif
87 template <typename Alloc>
88 void run_test_4(void)
90 typedef typename nova::dsp_thread_queue_item<dummy_runnable, Alloc> dsp_thread_queue_item;
91 typedef typename nova::dsp_thread_queue<dummy_runnable, Alloc> dsp_thread_queue;
93 typedef typename nova::dsp_threads<dummy_runnable, nova::nop_thread_init, Alloc> dsp_threads;
94 typedef std::auto_ptr<dsp_thread_queue> dsp_thread_queue_ptr;
96 dsp_threads t(1);
97 t.start_threads();
99 dsp_thread_queue_ptr q (new dsp_thread_queue(2));
101 dsp_thread_queue_item * item1 = q->allocate_queue_item(dummy, typename dsp_thread_queue_item::successor_list(), 1);
103 typename dsp_thread_queue_item::successor_list sl(1);
104 sl[0] = item1;
106 dsp_thread_queue_item * item2 = q->allocate_queue_item(dummy, sl, 0);
107 q->add_initially_runnable(item2);
109 t.reset_queue(MOVE(q));
111 t.run();
113 t.terminate_threads();
115 BOOST_REQUIRE_EQUAL(item1->get_job().i, 1);
116 BOOST_REQUIRE_EQUAL(item2->get_job().i, 1);
121 BOOST_AUTO_TEST_CASE( dsp_thread_test_4 )
123 run_test_4<std::allocator<void*> >();
124 run_test_4<nova::rt_pool_allocator<void*> >();
127 template <typename Alloc>
128 void run_test_5(void)
130 typedef nova::dsp_thread_queue_item<dummy_runnable, Alloc> dsp_thread_queue_item;
131 typedef nova::dsp_thread_queue<dummy_runnable, Alloc> dsp_thread_queue;
132 typedef nova::dsp_threads<dummy_runnable, nova::nop_thread_init, Alloc> dsp_threads;
134 typedef std::auto_ptr<dsp_thread_queue> dsp_thread_queue_ptr;
136 dsp_threads t(2);
137 t.start_threads();
139 dsp_thread_queue_ptr q (new dsp_thread_queue(5));
141 dsp_thread_queue_item * item1 = q->allocate_queue_item(dummy, typename dsp_thread_queue_item::successor_list(), 4);
143 typename dsp_thread_queue_item::successor_list sl(1);
144 sl[0] = item1;
146 dsp_thread_queue_item * item2 = q->allocate_queue_item(dummy, sl, 0);
147 q->add_initially_runnable(item2);
149 dsp_thread_queue_item * item3 = q->allocate_queue_item(dummy, sl, 0);
150 q->add_initially_runnable(item3);
152 dsp_thread_queue_item * item4 = q->allocate_queue_item(dummy, sl, 0);
153 q->add_initially_runnable(item4);
155 dsp_thread_queue_item * item5 = q->allocate_queue_item(dummy, sl, 0);
156 q->add_initially_runnable(item5);
158 t.reset_queue(MOVE(q));
160 t.run();
162 t.terminate_threads();
164 BOOST_REQUIRE_EQUAL(item1->get_job().i, 1);
165 BOOST_REQUIRE_EQUAL(item2->get_job().i, 1);
166 BOOST_REQUIRE_EQUAL(item3->get_job().i, 1);
167 BOOST_REQUIRE_EQUAL(item4->get_job().i, 1);
168 BOOST_REQUIRE_EQUAL(item5->get_job().i, 1);
173 BOOST_AUTO_TEST_CASE( dsp_thread_test_5 )
175 run_test_5<std::allocator<void*> >();
176 run_test_5<nova::rt_pool_allocator<void*> >();
179 template <typename Alloc>
180 void run_test_6(void)
182 typedef nova::dsp_thread_queue_item<dummy_runnable, Alloc> dsp_thread_queue_item;
183 typedef nova::dsp_thread_queue<dummy_runnable, Alloc> dsp_thread_queue;
184 typedef nova::dsp_threads<dummy_runnable, nova::nop_thread_init, Alloc> dsp_threads;
186 typedef std::auto_ptr<dsp_thread_queue> dsp_thread_queue_ptr;
188 dsp_threads t(2);
189 t.start_threads();
191 dsp_thread_queue_ptr q (new dsp_thread_queue(20));
193 std::vector<dsp_thread_queue_item*> items;
195 for (int i = 0; i != 20; ++i)
197 items.push_back(q->allocate_queue_item(dummy, typename dsp_thread_queue_item::successor_list(), 0));
198 q->add_initially_runnable(items.back());
201 t.reset_queue(MOVE(q));
203 const int iterations = 10000;
205 for (int i = 0; i != iterations; ++i)
207 for (int item = 0; item != 20; ++item)
208 BOOST_REQUIRE_EQUAL(items[item]->get_job().i, i);
209 t.run();
212 t.terminate_threads();
214 for (int i = 0; i != 20; ++i)
215 BOOST_REQUIRE_EQUAL(items[i]->get_job().i, iterations);
218 BOOST_AUTO_TEST_CASE( dsp_thread_test_6 )
220 run_test_6<std::allocator<void*> >();
221 run_test_6<nova::rt_pool_allocator<void*> >();