All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ThreadPool.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_UTIL_THREADPOOL_THREADPOOL_H_
23 #define _BLAZE_UTIL_THREADPOOL_THREADPOOL_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <boost/bind.hpp>
31 #include <boost/thread/condition.hpp>
32 #include <boost/thread/mutex.hpp>
33 #include <boost/type_traits.hpp>
34 #include <boost/utility/result_of.hpp>
35 #include <blaze/util/NonCopyable.h>
36 #include <blaze/util/PtrVector.h>
38 #include <blaze/util/Thread.h>
42 #include <blaze/util/Types.h>
43 
44 
45 namespace blaze {
46 
47 //=================================================================================================
48 //
49 // CLASS DEFINITION
50 //
51 //=================================================================================================
52 
53 //*************************************************************************************************
222 class ThreadPool : private NonCopyable
223 {
224  private:
225  //**Type definitions****************************************************************************
228  typedef boost::mutex Mutex;
229  typedef Mutex::scoped_lock Lock;
230  typedef boost::condition_variable Condition;
231  //**********************************************************************************************
232 
233  public:
234  //**Constructor*********************************************************************************
237  explicit ThreadPool( size_t n );
239  //**********************************************************************************************
240 
241  //**Destructor**********************************************************************************
244  ~ThreadPool();
246  //**********************************************************************************************
247 
248  //**Get functions*******************************************************************************
251  inline bool isEmpty() const;
252  inline size_t size() const;
253  inline size_t active() const;
254  inline size_t ready() const;
256  //**********************************************************************************************
257 
258  //**Scheduling functions************************************************************************
261  template< typename Callable >
262  void schedule( Callable func );
263 
264  template< typename Callable, typename A1 >
265  void schedule( Callable func, A1 a1 );
266 
267  template< typename Callable, typename A1, typename A2 >
268  void schedule( Callable func, A1 a1, A2 a2 );
269 
270  template< typename Callable, typename A1, typename A2, typename A3 >
271  void schedule( Callable func, A1 a1, A2 a2, A3 a3 );
272 
273  template< typename Callable, typename A1, typename A2, typename A3, typename A4 >
274  void schedule( Callable func, A1 a1, A2 a2, A3 a3, A4 a4 );
275 
276  template< typename Callable, typename A1, typename A2, typename A3, typename A4, typename A5 >
277  void schedule( Callable func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 );
279  //**********************************************************************************************
280 
281  //**Utility functions***************************************************************************
284  void resize( size_t n );
285  void wait();
286  void clear();
288  //**********************************************************************************************
289 
290  private:
291  //**Thread functions****************************************************************************
294  void createThread();
295  bool executeTask();
297  //**********************************************************************************************
298 
299  //**Member variables****************************************************************************
302  volatile size_t total_;
303  volatile size_t expected_;
304 
306  volatile size_t active_;
309  mutable Mutex mutex_;
312 
313  //**********************************************************************************************
314 
315  //**Friend declarations*************************************************************************
317  friend class Thread;
319  //**********************************************************************************************
320 };
321 //*************************************************************************************************
322 
323 
324 
325 
326 //=================================================================================================
327 //
328 // GET FUNCTIONS
329 //
330 //=================================================================================================
331 
332 //*************************************************************************************************
337 inline bool ThreadPool::isEmpty() const
338 {
339  Lock lock( mutex_ );
340  return taskqueue_.isEmpty();
341 }
342 //*************************************************************************************************
343 
344 
345 //*************************************************************************************************
350 inline size_t ThreadPool::size() const
351 {
352  Lock lock( mutex_ );
353  return expected_;
354 }
355 //*************************************************************************************************
356 
357 
358 //*************************************************************************************************
363 inline size_t ThreadPool::active() const
364 {
365  Lock lock( mutex_ );
366  return active_;
367 }
368 //*************************************************************************************************
369 
370 
371 //*************************************************************************************************
376 inline size_t ThreadPool::ready() const
377 {
378  Lock lock( mutex_ );
379  return expected_ - active_;
380 }
381 //*************************************************************************************************
382 
383 
384 
385 
386 //=================================================================================================
387 //
388 // SCHEDULING FUNCTIONS
389 //
390 //=================================================================================================
391 
392 //*************************************************************************************************
401 template< typename Callable > // Task type
402 void ThreadPool::schedule( Callable func )
403 {
404  BLAZE_STATIC_ASSERT( boost::function_traits<Callable()>::arity == 0 );
405  BLAZE_STATIC_ASSERT( boost::is_void< typename boost::result_of<Callable()>::type >::value );
406 
407  using threadpool::TaskID;
409 
410  Lock lock( mutex_ );
411  TaskID task( new FuncWrapper<Callable>( func ) );
412  taskqueue_.push( task );
413  waitForTask_.notify_one();
414 }
415 //*************************************************************************************************
416 
417 
418 //*************************************************************************************************
428 template< typename Callable // Type of the function/functor
429  , typename A1 > // Type of the first argument
430 void ThreadPool::schedule( Callable func, A1 a1 )
431 {
432  BLAZE_STATIC_ASSERT( boost::function_traits<Callable()>::arity == 1 );
433  BLAZE_STATIC_ASSERT( boost::is_void< typename boost::result_of<Callable()>::type >::value );
434 
435  using threadpool::TaskID;
437 
438  Lock lock( mutex_ );
439  TaskID task( new FuncWrapper<Callable>( boost::bind( func, a1 ) ) );
440  taskqueue_.push( task );
441  waitForTask_.notify_one();
442 }
443 //*************************************************************************************************
444 
445 
446 //*************************************************************************************************
457 template< typename Callable // Type of the function/functor
458  , typename A1 // Type of the first argument
459  , typename A2 > // Type of the second argument
460 void ThreadPool::schedule( Callable func, A1 a1, A2 a2 )
461 {
462  BLAZE_STATIC_ASSERT( boost::function_traits<Callable()>::arity == 2 );
463  BLAZE_STATIC_ASSERT( boost::is_void< typename boost::result_of<Callable()>::type >::value );
464 
465  using threadpool::TaskID;
467 
468  Lock lock( mutex_ );
469  TaskID task( new FuncWrapper<Callable>( boost::bind( func, a1, a2 ) ) );
470  taskqueue_.push( task );
471  waitForTask_.notify_one();
472 }
473 //*************************************************************************************************
474 
475 
476 //*************************************************************************************************
488 template< typename Callable // Type of the function/functor
489  , typename A1 // Type of the first argument
490  , typename A2 // Type of the second argument
491  , typename A3 > // Type of the third argument
492 void ThreadPool::schedule( Callable func, A1 a1, A2 a2, A3 a3 )
493 {
494  BLAZE_STATIC_ASSERT( boost::function_traits<Callable()>::arity == 3 );
495  BLAZE_STATIC_ASSERT( boost::is_void< typename boost::result_of<Callable()>::type >::value );
496 
497  using threadpool::TaskID;
499 
500  Lock lock( mutex_ );
501  TaskID task( new FuncWrapper<Callable>( boost::bind( func, a1, a2, a3 ) ) );
502  taskqueue_.push( task );
503  waitForTask_.notify_one();
504 }
505 //*************************************************************************************************
506 
507 
508 //*************************************************************************************************
521 template< typename Callable // Type of the function/functor
522  , typename A1 // Type of the first argument
523  , typename A2 // Type of the second argument
524  , typename A3 // Type of the third argument
525  , typename A4 > // Type of the fourth argument
526 void ThreadPool::schedule( Callable func, A1 a1, A2 a2, A3 a3, A4 a4 )
527 {
528  BLAZE_STATIC_ASSERT( boost::function_traits<Callable()>::arity == 4 );
529  BLAZE_STATIC_ASSERT( boost::is_void< typename boost::result_of<Callable()>::type >::value );
530 
531  using threadpool::TaskID;
533 
534  Lock lock( mutex_ );
535  TaskID task( new FuncWrapper<Callable>( boost::bind( func, a1, a2, a3, a4 ) ) );
536  taskqueue_.push( task );
537  waitForTask_.notify_one();
538 }
539 //*************************************************************************************************
540 
541 
542 //*************************************************************************************************
556 template< typename Callable // Type of the function/functor
557  , typename A1 // Type of the first argument
558  , typename A2 // Type of the second argument
559  , typename A3 // Type of the third argument
560  , typename A4 // Type of the fourth argument
561  , typename A5 > // Type of the fifth argument
562 void ThreadPool::schedule( Callable func, A1 a1, A2 a2, A3 a3, A4 a4, A5 a5 )
563 {
564  BLAZE_STATIC_ASSERT( boost::function_traits<Callable()>::arity == 5 );
565  BLAZE_STATIC_ASSERT( boost::is_void< typename boost::result_of<Callable()>::type >::value );
566 
567  using threadpool::TaskID;
569 
570  Lock lock( mutex_ );
571  TaskID task( new FuncWrapper<Callable>( boost::bind( func, a1, a2, a3, a4, a5 ) ) );
572  taskqueue_.push( task );
573  waitForTask_.notify_one();
574 }
575 //*************************************************************************************************
576 
577 } // namespace blaze
578 
579 #endif