@@ -15,6 +15,15 @@ template <int NWorkers = 0>
15
15
class work_queue
16
16
{
17
17
public:
18
+ struct task_t {
19
+ boost::shared_ptr<boost::shared_lock<boost::shared_mutex> > m_lock;
20
+ boost::function<void ()> m_task;
21
+ task_t (const boost::function<void ()>& task, boost::shared_mutex& m)
22
+ : m_lock(new boost::shared_lock<boost::shared_mutex>(m)), m_task(task){}
23
+ void operator ()(){
24
+ m_task ();
25
+ }
26
+ };
18
27
work_queue ()
19
28
{
20
29
work_ctrl_ = new boost::asio::io_service::work (io_service_);
@@ -26,6 +35,22 @@ class work_queue
26
35
}
27
36
}
28
37
38
+ /* *
39
+ * @warning that this will block the concurrent addition of new tasks.
40
+ * In this case, you will have a deadlock: the new task won't get its shared
41
+ * lock, and this function won't get its unique lock.
42
+ * It would probably be wiser to have something here that tries to get a
43
+ * lock for /some/ time, then instead sleeps for a few milliseconds,
44
+ * enabling other tasks to get into the queue.
45
+ * On the other hand, this would still waste the time when everyone is
46
+ * waiting. So currently the use case is the simple one: Put all tasks in
47
+ * the queue, and /then/ call block_until_tasks_done. Don't generate tasks
48
+ * asynchronously.
49
+ */
50
+ void block_until_tasks_done (){
51
+ boost::unique_lock<boost::shared_mutex> foo (access_);
52
+ }
53
+
29
54
virtual ~work_queue () {
30
55
delete work_ctrl_;
31
56
@@ -37,10 +62,11 @@ class work_queue
37
62
void post (const TTask& task) {
38
63
// c++11
39
64
// io_service_.dispatch(std::move(task));
40
- io_service_.dispatch (task);
65
+ io_service_.dispatch (task_t ( task, access_) );
41
66
}
42
67
43
68
private:
69
+ boost::shared_mutex access_;
44
70
boost::asio::io_service io_service_;
45
71
boost::thread_group threads_;
46
72
boost::asio::io_service::work *work_ctrl_;
@@ -146,6 +172,7 @@ struct pool_alloc_tester{
146
172
BOOST_REQUIRE_GE (allocator->pool_size (M ()), pool_size);
147
173
BOOST_REQUIRE_GE (allocator->pool_free_count (M ()), 0lu);
148
174
}
175
+ std::cout << " i:" << i << " ptr:" << ptr << std::endl;
149
176
*done = true ;
150
177
}
151
178
};
@@ -165,30 +192,29 @@ static void test_pooled_allocator_multi_threaded() {
165
192
pool_alloc_tester<memory_space> tester (allocator, boost_mutex, ALLOC_SIZE);
166
193
167
194
// tbb::parallel_for_each(pointers.begin(), pointers.end(), tester);
168
- { work_queue<> q ;
195
+ { work_queue<> Q ;
169
196
for (size_t i = 0 ; i < pointers.size (); i++) {
170
- q .post (boost::bind (&pool_alloc_tester<memory_space>::operator (),
197
+ Q .post (boost::bind (&pool_alloc_tester<memory_space>::operator (),
171
198
&tester, &pointers[i], i, &done[i]));
172
199
}
173
- }
200
+ Q. block_until_tasks_done ();
174
201
175
- for (size_t i = 0 ; i < pointers.size (); i++) {
176
- BOOST_REQUIRE (done[i]);
177
- // std::cout << "i:" << i << " pointers[i]:" << pointers[i] << std::endl;
178
- BOOST_REQUIRE (pointers[i] != NULL );
179
- }
202
+ for (size_t i = 0 ; i < pointers.size (); i++) {
203
+ BOOST_REQUIRE (done[i]);
204
+ // std::cout << "i:" << i << " pointers[i]:" << pointers[i] << std::endl;
205
+ BOOST_REQUIRE (pointers[i] != NULL );
206
+ }
180
207
181
- BOOST_CHECK_GE (allocator.pool_size (m), pointers.size () * ALLOC_SIZE);
182
- BOOST_CHECK_LE (allocator.pool_count (m), 10 * pointers.size ());
208
+ BOOST_CHECK_GE (allocator.pool_size (m), pointers.size () * ALLOC_SIZE);
209
+ BOOST_CHECK_LE (allocator.pool_count (m), 10 * pointers.size ());
183
210
184
- size_t count = allocator.pool_count (m);
185
- BOOST_CHECK_GE (count, pointers.size ());
211
+ size_t count = allocator.pool_count (m);
212
+ BOOST_CHECK_GE (count, pointers.size ());
186
213
187
- { work_queue<> q;
188
214
pool_destroy_tester<memory_space> tester2 (allocator, boost_mutex, ALLOC_SIZE);
189
215
// tbb::parallel_for_each(pointers.begin(), pointers.end(), tester2);
190
216
for (size_t i = 0 ; i < pointers.size (); i++) {
191
- q .post (boost::bind ( &pool_destroy_tester<memory_space>::operator (), &tester2, &pointers[i]));
217
+ Q .post (boost::bind ( &pool_destroy_tester<memory_space>::operator (), &tester2, &pointers[i]));
192
218
}
193
219
}
194
220
0 commit comments