Reference documentation for deal.II version 8.4.1
thread_management.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2015 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii__thread_management_h
17 #define dealii__thread_management_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/exceptions.h>
22 #include <deal.II/base/template_constraints.h>
23 #include <deal.II/base/std_cxx11/tuple.h>
24 #include <deal.II/base/std_cxx11/function.h>
25 #include <deal.II/base/std_cxx11/shared_ptr.h>
26 #include <deal.II/base/std_cxx11/bind.h>
27 
28 #ifdef DEAL_II_WITH_THREADS
29 # include <deal.II/base/std_cxx11/thread.h>
30 # include <deal.II/base/std_cxx11/mutex.h>
31 # include <deal.II/base/std_cxx11/condition_variable.h>
32 #endif
33 
34 #include <iterator>
35 #include <vector>
36 #include <list>
37 #include <utility>
38 
39 
40 #ifdef DEAL_II_WITH_THREADS
41 # ifdef DEAL_II_USE_MT_POSIX
42 # include <pthread.h>
43 # endif
44 # include <tbb/task.h>
45 #endif
46 
47 
48 
49 DEAL_II_NAMESPACE_OPEN
50 
53 
54 
62 namespace Threads
63 {
78  {
79  public:
94  class ScopedLock
95  {
96  public:
102 
108  };
109 
114  inline void acquire () const {}
115 
120  inline void release () const {}
121  };
122 
123 
124 
143  {
144  public:
150  inline void signal () const {}
151 
157  inline void broadcast () const {}
158 
166  inline void wait (DummyThreadMutex &) const {}
167  };
168 
169 
170 
187  {
188  public:
194  DummyBarrier (const unsigned int count,
195  const char *name = 0,
196  void *arg = 0);
197 
202  int wait () const
203  {
204  return 0;
205  }
206 
210  void dump () const {}
211 
220  DeclException1 (ExcBarrierSizeNotUseful,
221  int,
222  << "In single-thread mode, barrier sizes other than 1 are not "
223  << "useful. You gave " << arg1 << ".");
224 
226  };
227 
228 
229 #ifdef DEAL_II_WITH_THREADS
230 
247  class Mutex
248  {
249  public:
265  {
266  public:
271  {
272  mutex.acquire();
273  }
274 
280  {
281  mutex.release ();
282  }
283 
284  private:
289  };
290 
294  Mutex ()
295  {}
296 
301  Mutex (const Mutex &)
302  :
303  mutex()
304  {}
305 
306 
310  inline void acquire ()
311  {
312  mutex.lock();
313  }
314 
318  inline void release ()
319  {
320  mutex.unlock();
321  }
322 
323  private:
327  std_cxx11::mutex mutex;
328 
333  friend class ConditionVariable;
334  };
335 
336 
344  {
345  public:
350  inline void signal ()
351  {
352  condition_variable.notify_one();
353  }
354 
359  inline void broadcast ()
360  {
361  condition_variable.notify_all();
362  }
363 
373  inline void wait (Mutex &mutex)
374  {
375  std_cxx11::unique_lock<std_cxx11::mutex> lock(mutex.mutex,
376  std_cxx11::adopt_lock);
377  condition_variable.wait (lock);
378  }
379 
380  private:
384  std_cxx11::condition_variable condition_variable;
385  };
386 
387 
404  {
405  public:
409  PosixThreadBarrier (const unsigned int count,
410  const char *name = 0,
411  void *arg = 0);
412 
417 
424  int wait ();
425 
426  private:
431 #ifndef DEAL_II_USE_MT_POSIX_NO_BARRIERS
432  pthread_barrier_t barrier;
433 #else
434  unsigned int count;
435 #endif
436  };
437 
438 
444 
445 #else
446 
451  typedef DummyThreadMutex Mutex;
452 
459 
465  typedef DummyBarrier Barrier;
466 #endif
467 
468 }
469 
470 
471 namespace Threads
472 {
473 
503  unsigned int n_existing_threads ();
504 
516  unsigned int this_thread_id ();
517 
532  template <typename ForwardIterator>
533  std::vector<std::pair<ForwardIterator,ForwardIterator> >
534  split_range (const ForwardIterator &begin,
535  const ForwardIterator &end,
536  const unsigned int n_intervals);
537 
546  std::vector<std::pair<unsigned int,unsigned int> >
547  split_interval (const unsigned int begin,
548  const unsigned int end,
549  const unsigned int n_intervals);
550 
562  namespace internal
563  {
579  void handle_std_exception (const std::exception &exc);
580 
588  void handle_unknown_exception ();
589 
597  void register_thread ();
598 
606  void deregister_thread ();
607  }
608 
613 } // end declarations of namespace Threads
614 
615 /* ----------- implementation of functions in namespace Threads ---------- */
616 #ifndef DOXYGEN
617 namespace Threads
618 {
619  template <typename ForwardIterator>
620  std::vector<std::pair<ForwardIterator,ForwardIterator> >
621  split_range (const ForwardIterator &begin,
622  const ForwardIterator &end,
623  const unsigned int n_intervals)
624  {
625  typedef std::pair<ForwardIterator,ForwardIterator> IteratorPair;
626 
627  // in non-multithreaded mode, we often have the case that this
628  // function is called with n_intervals==1, so have a shortcut here
629  // to handle that case efficiently
630 
631  if (n_intervals==1)
632  return (std::vector<IteratorPair>
633  (1, IteratorPair(begin, end)));
634 
635  // if more than one interval requested, do the full work
636  const unsigned int n_elements = std::distance (begin, end);
637  const unsigned int n_elements_per_interval = n_elements / n_intervals;
638  const unsigned int residual = n_elements % n_intervals;
639 
640  std::vector<IteratorPair> return_values (n_intervals);
641 
642  return_values[0].first = begin;
643  for (unsigned int i=0; i<n_intervals; ++i)
644  {
645  if (i != n_intervals-1)
646  {
647  return_values[i].second = return_values[i].first;
648  // note: the cast is performed to avoid a warning of gcc
649  // that in the library `dist>=0' is checked (dist has a
650  // template type, which here is unsigned if no cast is
651  // performed)
652  std::advance (return_values[i].second,
653  static_cast<signed int>(n_elements_per_interval));
654  // distribute residual in division equally among the first
655  // few subintervals
656  if (i < residual)
657  ++return_values[i].second;
658 
659  return_values[i+1].first = return_values[i].second;
660  }
661  else
662  return_values[i].second = end;
663  }
664  return return_values;
665  }
666 }
667 
668 #endif // DOXYGEN
669 
670 namespace Threads
671 {
672  namespace internal
673  {
681  template <typename RT> struct return_value
682  {
683  private:
684  RT value;
685  public:
686  inline return_value () : value() {}
687 
688  inline RT get () const
689  {
690  return value;
691  }
692 
693  inline void set (RT v)
694  {
695  value = v;
696  }
697  };
698 
699 
709  template <typename RT> struct return_value<RT &>
710  {
711  private:
712  RT *value;
713  public:
714  inline return_value () : value(0) {}
715 
716  inline RT &get () const
717  {
718  return *value;
719  }
720  inline void set (RT &v)
721  {
722  value = &v;
723  }
724  };
725 
726 
735  template <> struct return_value<void>
736  {
737  static inline void get () {}
738  };
739  }
740 
741 
742 
743  namespace internal
744  {
745  template <typename RT>
746  inline void call (const std_cxx11::function<RT ()> &function,
747  internal::return_value<RT> &ret_val)
748  {
749  ret_val.set (function());
750  }
751 
752 
753  inline void call (const std_cxx11::function<void ()> &function,
754  internal::return_value<void> &)
755  {
756  function();
757  }
758  }
759 
760 
761 
762  namespace internal
763  {
773  template <typename RT, typename ArgList,
774  int length = std_cxx11::tuple_size<ArgList>::value>
775  struct fun_ptr_helper;
776 
777 
784  template <typename RT, typename ArgList>
785  struct fun_ptr_helper<RT, ArgList, 0>
786  {
787  typedef RT (type) ();
788  };
789 
790 
797  template <typename RT, typename ArgList>
798  struct fun_ptr_helper<RT, ArgList, 1>
799  {
800  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type);
801  };
802 
803 
810  template <typename RT, typename ArgList>
811  struct fun_ptr_helper<RT, ArgList, 2>
812  {
813  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
814  typename std_cxx11::tuple_element<1,ArgList>::type);
815  };
816 
817 
824  template <typename RT, typename ArgList>
825  struct fun_ptr_helper<RT, ArgList, 3>
826  {
827  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
828  typename std_cxx11::tuple_element<1,ArgList>::type,
829  typename std_cxx11::tuple_element<2,ArgList>::type);
830  };
831 
832 
839  template <typename RT, typename ArgList>
840  struct fun_ptr_helper<RT, ArgList, 4>
841  {
842  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
843  typename std_cxx11::tuple_element<1,ArgList>::type,
844  typename std_cxx11::tuple_element<2,ArgList>::type,
845  typename std_cxx11::tuple_element<3,ArgList>::type);
846  };
847 
848 
855  template <typename RT, typename ArgList>
856  struct fun_ptr_helper<RT, ArgList, 5>
857  {
858  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
859  typename std_cxx11::tuple_element<1,ArgList>::type,
860  typename std_cxx11::tuple_element<2,ArgList>::type,
861  typename std_cxx11::tuple_element<3,ArgList>::type,
862  typename std_cxx11::tuple_element<4,ArgList>::type);
863  };
864 
865 
872  template <typename RT, typename ArgList>
873  struct fun_ptr_helper<RT, ArgList, 6>
874  {
875  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
876  typename std_cxx11::tuple_element<1,ArgList>::type,
877  typename std_cxx11::tuple_element<2,ArgList>::type,
878  typename std_cxx11::tuple_element<3,ArgList>::type,
879  typename std_cxx11::tuple_element<4,ArgList>::type,
880  typename std_cxx11::tuple_element<5,ArgList>::type);
881  };
882 
883 
890  template <typename RT, typename ArgList>
891  struct fun_ptr_helper<RT, ArgList, 7>
892  {
893  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
894  typename std_cxx11::tuple_element<1,ArgList>::type,
895  typename std_cxx11::tuple_element<2,ArgList>::type,
896  typename std_cxx11::tuple_element<3,ArgList>::type,
897  typename std_cxx11::tuple_element<4,ArgList>::type,
898  typename std_cxx11::tuple_element<5,ArgList>::type,
899  typename std_cxx11::tuple_element<6,ArgList>::type);
900  };
901 
902 
909  template <typename RT, typename ArgList>
910  struct fun_ptr_helper<RT, ArgList, 8>
911  {
912  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
913  typename std_cxx11::tuple_element<1,ArgList>::type,
914  typename std_cxx11::tuple_element<2,ArgList>::type,
915  typename std_cxx11::tuple_element<3,ArgList>::type,
916  typename std_cxx11::tuple_element<4,ArgList>::type,
917  typename std_cxx11::tuple_element<5,ArgList>::type,
918  typename std_cxx11::tuple_element<6,ArgList>::type,
919  typename std_cxx11::tuple_element<7,ArgList>::type);
920  };
921 
922 
929  template <typename RT, typename ArgList>
930  struct fun_ptr_helper<RT, ArgList, 9>
931  {
932  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
933  typename std_cxx11::tuple_element<1,ArgList>::type,
934  typename std_cxx11::tuple_element<2,ArgList>::type,
935  typename std_cxx11::tuple_element<3,ArgList>::type,
936  typename std_cxx11::tuple_element<4,ArgList>::type,
937  typename std_cxx11::tuple_element<5,ArgList>::type,
938  typename std_cxx11::tuple_element<6,ArgList>::type,
939  typename std_cxx11::tuple_element<7,ArgList>::type,
940  typename std_cxx11::tuple_element<8,ArgList>::type);
941  };
942 
943 
944 
951  template <typename RT, typename ArgList>
952  struct fun_ptr_helper<RT, ArgList, 10>
953  {
954  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
955  typename std_cxx11::tuple_element<1,ArgList>::type,
956  typename std_cxx11::tuple_element<2,ArgList>::type,
957  typename std_cxx11::tuple_element<3,ArgList>::type,
958  typename std_cxx11::tuple_element<4,ArgList>::type,
959  typename std_cxx11::tuple_element<5,ArgList>::type,
960  typename std_cxx11::tuple_element<6,ArgList>::type,
961  typename std_cxx11::tuple_element<7,ArgList>::type,
962  typename std_cxx11::tuple_element<8,ArgList>::type,
963  typename std_cxx11::tuple_element<9,ArgList>::type);
964  };
965 
966 
967 
978  template <typename RT, typename ArgList>
979  struct fun_ptr
980  {
981  typedef typename fun_ptr_helper<RT,ArgList>::type type;
982  };
983  }
984 
985 
986 
987  namespace internal
988  {
989 #ifdef DEAL_II_WITH_THREADS
990 
1001  template <typename RT>
1003  {
1007  std_cxx11::thread thread;
1008 
1017  std_cxx11::shared_ptr<return_value<RT> > ret_val;
1018 
1051 
1056 
1061  :
1062  thread_is_active (false)
1063  {}
1064 
1065  ~ThreadDescriptor ()
1066  {
1067  if (!thread_is_active)
1068  return;
1069  thread.detach();
1070  thread_is_active = false;
1071  }
1072 
1077  void start (const std_cxx11::function<RT ()> &function)
1078  {
1079  thread_is_active = true;
1080  ret_val.reset(new return_value<RT>());
1081  thread = std_cxx11::thread (thread_entry_point, function, ret_val);
1082  }
1083 
1084 
1088  void join ()
1089  {
1090  // see if the thread hasn't been joined yet. if it has, then
1091  // join() is a no-op. use schmidt's double-checking strategy
1092  // to use the mutex only when necessary
1093  if (thread_is_active == false)
1094  return;
1095 
1096  Mutex::ScopedLock lock (thread_is_active_mutex);
1097  if (thread_is_active == true)
1098  {
1099  Assert (thread.joinable(), ExcInternalError());
1100  thread.join ();
1101  thread_is_active = false;
1102  }
1103  }
1104 
1105  private:
1106 
1110  static
1111  void thread_entry_point (const std_cxx11::function<RT ()> function,
1112  std_cxx11::shared_ptr<return_value<RT> > ret_val)
1113  {
1114  // call the function in question. since an exception that is
1115  // thrown from one of the called functions will not propagate
1116  // to the main thread, it will kill the program if not treated
1117  // here before we return to the operating system's thread
1118  // library
1119  internal::register_thread ();
1120  try
1121  {
1122  call (function, *ret_val);
1123  }
1124  catch (const std::exception &exc)
1125  {
1126  internal::handle_std_exception (exc);
1127  }
1128  catch (...)
1129  {
1130  internal::handle_unknown_exception ();
1131  }
1132  internal::deregister_thread ();
1133  }
1134  };
1135 
1136 #else
1137 
1145  template <typename RT>
1146  struct ThreadDescriptor
1147  {
1152  std_cxx11::shared_ptr<return_value<RT> > ret_val;
1153 
1158  void start (const std_cxx11::function<RT ()> &function)
1159  {
1160  ret_val.reset(new return_value<RT>());
1161  call (function, *ret_val);
1162  }
1163 
1167  void join ()
1168  {}
1169  };
1170 
1171 #endif
1172  }
1173 
1174 
1197  template <typename RT = void>
1198  class Thread
1199  {
1200  public:
1204  Thread (const std_cxx11::function<RT ()> &function)
1205  :
1206  thread_descriptor (new internal::ThreadDescriptor<RT>())
1207  {
1208  // in a second step, start the thread.
1209  thread_descriptor->start (function);
1210  }
1211 
1217  Thread () {}
1218 
1222  Thread (const Thread<RT> &t)
1223  :
1225  {}
1226 
1232  void join () const
1233  {
1234  if (thread_descriptor)
1235  thread_descriptor->join ();
1236  }
1237 
1243  {
1244  join ();
1245  return thread_descriptor->ret_val->get();
1246  }
1247 
1252  bool valid () const
1253  {
1254  return static_cast<bool>(thread_descriptor);
1255  }
1256 
1257 
1263  bool operator == (const Thread &t)
1264  {
1266  }
1267 
1268  private:
1275  std_cxx11::shared_ptr<internal::ThreadDescriptor<RT> > thread_descriptor;
1276  };
1277 
1278 
1279  namespace internal
1280  {
1288  template <typename T>
1290  {
1291  static T act (T &t)
1292  {
1293  return t;
1294  }
1295  };
1296 
1297 
1298 
1306  template <typename T>
1307  struct maybe_make_ref<T &>
1308  {
1309  static std_cxx11::reference_wrapper<T> act (T &t)
1310  {
1311  return std_cxx11::ref(t);
1312  }
1313  };
1314  }
1315 
1316 
1317 
1318  namespace internal
1319  {
1333  template <typename RT, typename ArgList, int length>
1334  class fun_encapsulator;
1335 
1336 
1337 // ----------- encapsulators for function objects
1338 
1344  template <typename RT, typename ArgList>
1345  class fun_encapsulator<RT, ArgList, 0>
1346  {
1347  public:
1348  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1349  : function (*function)
1350  {}
1351 
1352  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1353  : function (function)
1354  {}
1355 
1356  inline
1357  Thread<RT>
1358  operator() ()
1359  {
1360  return Thread<RT> (function);
1361  }
1362 
1363  private:
1364  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1365  };
1366 
1372  template <typename RT, typename ArgList>
1373  class fun_encapsulator<RT, ArgList, 1>
1374  {
1375  public:
1376  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1377  : function (*function)
1378  {}
1379 
1380  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1381  : function (function)
1382  {}
1383 
1384  inline
1385  Thread<RT>
1386  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1)
1387  {
1388  return
1389  Thread<RT>
1390  (std_cxx11::bind (function,
1391  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1)));
1392  }
1393 
1394  private:
1395  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1396  };
1397 
1403  template <typename RT, typename ArgList>
1404  class fun_encapsulator<RT, ArgList, 2>
1405  {
1406  public:
1407  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1408  : function (*function)
1409  {}
1410 
1411  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1412  : function (function)
1413  {}
1414 
1415  inline
1416  Thread<RT>
1417  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1418  typename std_cxx11::tuple_element<1,ArgList>::type arg2)
1419  {
1420  return
1421  Thread<RT>
1422  (std_cxx11::bind (function,
1423  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1424  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2)));
1425  }
1426 
1427  private:
1428  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1429  };
1430 
1436  template <typename RT, typename ArgList>
1437  class fun_encapsulator<RT, ArgList, 3>
1438  {
1439  public:
1440  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1441  : function (*function)
1442  {}
1443 
1444  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1445  : function (function)
1446  {}
1447 
1448  inline
1449  Thread<RT>
1450  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1451  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1452  typename std_cxx11::tuple_element<2,ArgList>::type arg3)
1453  {
1454  return
1455  Thread<RT>
1456  (std_cxx11::bind (function,
1457  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1458  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1459  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3)));
1460  }
1461 
1462  private:
1463  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1464  };
1465 
1471  template <typename RT, typename ArgList>
1472  class fun_encapsulator<RT, ArgList, 4>
1473  {
1474  public:
1475  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1476  : function (*function)
1477  {}
1478 
1479  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1480  : function (function)
1481  {}
1482 
1483  inline
1484  Thread<RT>
1485  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1486  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1487  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1488  typename std_cxx11::tuple_element<3,ArgList>::type arg4)
1489  {
1490  return
1491  Thread<RT>
1492  (std_cxx11::bind (function,
1493  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1494  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1495  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1496  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4)));
1497  }
1498 
1499  private:
1500  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1501  };
1502 
1508  template <typename RT, typename ArgList>
1509  class fun_encapsulator<RT, ArgList, 5>
1510  {
1511  public:
1512  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1513  : function (*function)
1514  {}
1515 
1516  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1517  : function (function)
1518  {}
1519 
1520  inline
1521  Thread<RT>
1522  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1523  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1524  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1525  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1526  typename std_cxx11::tuple_element<4,ArgList>::type arg5)
1527  {
1528  return
1529  Thread<RT>
1530  (std_cxx11::bind (function,
1531  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1532  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1533  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1534  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1535  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5)));
1536  }
1537 
1538  private:
1539  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1540  };
1541 
1547  template <typename RT, typename ArgList>
1548  class fun_encapsulator<RT, ArgList, 6>
1549  {
1550  public:
1551  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1552  : function (*function)
1553  {}
1554 
1555  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1556  : function (function)
1557  {}
1558 
1559  inline
1560  Thread<RT>
1561  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1562  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1563  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1564  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1565  typename std_cxx11::tuple_element<4,ArgList>::type arg5,
1566  typename std_cxx11::tuple_element<5,ArgList>::type arg6)
1567  {
1568  return
1569  Thread<RT>
1570  (std_cxx11::bind (function,
1571  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1572  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1573  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1574  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1575  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5),
1576  internal::maybe_make_ref<typename std_cxx11::tuple_element<5,ArgList>::type>::act(arg6)));
1577  }
1578 
1579  private:
1580  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1581  };
1582 
1588  template <typename RT, typename ArgList>
1589  class fun_encapsulator<RT, ArgList, 7>
1590  {
1591  public:
1592  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1593  : function (*function)
1594  {}
1595 
1596  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1597  : function (function)
1598  {}
1599 
1600  inline
1601  Thread<RT>
1602  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1603  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1604  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1605  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1606  typename std_cxx11::tuple_element<4,ArgList>::type arg5,
1607  typename std_cxx11::tuple_element<5,ArgList>::type arg6,
1608  typename std_cxx11::tuple_element<6,ArgList>::type arg7)
1609  {
1610  return
1611  Thread<RT>
1612  (std_cxx11::bind (function,
1613  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1614  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1615  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1616  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1617  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5),
1618  internal::maybe_make_ref<typename std_cxx11::tuple_element<5,ArgList>::type>::act(arg6),
1619  internal::maybe_make_ref<typename std_cxx11::tuple_element<6,ArgList>::type>::act(arg7)));
1620  }
1621 
1622  private:
1623  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1624  };
1625 
1631  template <typename RT, typename ArgList>
1632  class fun_encapsulator<RT, ArgList, 8>
1633  {
1634  public:
1635  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1636  : function (*function)
1637  {}
1638 
1639  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1640  : function (function)
1641  {}
1642 
1643  inline
1644  Thread<RT>
1645  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1646  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1647  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1648  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1649  typename std_cxx11::tuple_element<4,ArgList>::type arg5,
1650  typename std_cxx11::tuple_element<5,ArgList>::type arg6,
1651  typename std_cxx11::tuple_element<6,ArgList>::type arg7,
1652  typename std_cxx11::tuple_element<7,ArgList>::type arg8)
1653  {
1654  return
1655  Thread<RT>
1656  (std_cxx11::bind (function,
1657  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1658  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1659  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1660  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1661  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5),
1662  internal::maybe_make_ref<typename std_cxx11::tuple_element<5,ArgList>::type>::act(arg6),
1663  internal::maybe_make_ref<typename std_cxx11::tuple_element<6,ArgList>::type>::act(arg7),
1664  internal::maybe_make_ref<typename std_cxx11::tuple_element<7,ArgList>::type>::act(arg8)));
1665  }
1666 
1667  private:
1668  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1669  };
1670 
1676  template <typename RT, typename ArgList>
1677  class fun_encapsulator<RT, ArgList, 9>
1678  {
1679  public:
1680  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1681  : function (*function)
1682  {}
1683 
1684  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1685  : function (function)
1686  {}
1687 
1688  inline
1689  Thread<RT>
1690  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1691  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1692  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1693  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1694  typename std_cxx11::tuple_element<4,ArgList>::type arg5,
1695  typename std_cxx11::tuple_element<5,ArgList>::type arg6,
1696  typename std_cxx11::tuple_element<6,ArgList>::type arg7,
1697  typename std_cxx11::tuple_element<7,ArgList>::type arg8,
1698  typename std_cxx11::tuple_element<8,ArgList>::type arg9)
1699  {
1700  return
1701  Thread<RT>
1702  (std_cxx11::bind (function,
1703  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1704  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1705  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1706  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1707  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5),
1708  internal::maybe_make_ref<typename std_cxx11::tuple_element<5,ArgList>::type>::act(arg6),
1709  internal::maybe_make_ref<typename std_cxx11::tuple_element<6,ArgList>::type>::act(arg7),
1710  internal::maybe_make_ref<typename std_cxx11::tuple_element<7,ArgList>::type>::act(arg8),
1711  internal::maybe_make_ref<typename std_cxx11::tuple_element<8,ArgList>::type>::act(arg9)));
1712  }
1713 
1714  private:
1715  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1716  };
1717  }
1718 
1719 
1720 
1721 // ----------- thread starters for functions not taking any parameters
1722 
1731  template <typename RT>
1732  inline
1733  Thread<RT>
1734  new_thread (const std_cxx11::function<RT ()> &function)
1735  {
1736  return Thread<RT>(function);
1737  }
1738 
1745  template <typename RT>
1746  inline
1747  Thread<RT>
1748  new_thread (RT (*fun_ptr)())
1749  {
1750  return Thread<RT>(fun_ptr);
1751  }
1752 
1753 
1760  template <typename RT, typename C>
1761  inline
1762  Thread<RT>
1763  new_thread (RT (C::*fun_ptr)(),
1764  typename identity<C>::type &c)
1765  {
1766  return
1767  Thread<RT>
1768  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c)));
1769  }
1770 
1771 
1772 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
1773 
1779  template <typename RT, typename C>
1780  inline
1781  Thread<RT>
1782  new_thread (RT (C::*fun_ptr)() const,
1783  const typename identity<C>::type &c)
1784  {
1785  return
1786  Thread<RT>
1787  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c)));
1788  }
1789 #endif
1790 
1791 
1792 
1793 // ----------- thread starters for unary functions
1794 
1801  template <typename RT, typename Arg1>
1802  inline
1803  Thread<RT>
1804  new_thread (RT (*fun_ptr)(Arg1),
1805  typename identity<Arg1>::type arg1)
1806  {
1807  return
1808  Thread<RT>
1809  (std_cxx11::bind(fun_ptr,
1811  }
1812 
1813 
1814 
1821  template <typename RT, typename C, typename Arg1>
1822  inline
1823  Thread<RT>
1824  new_thread (RT (C::*fun_ptr)(Arg1),
1825  typename identity<C>::type &c,
1826  typename identity<Arg1>::type arg1)
1827  {
1828  return
1829  Thread<RT>
1830  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
1832  }
1833 
1834 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
1835 
1841  template <typename RT, typename C, typename Arg1>
1842  inline
1843  Thread<RT>
1844  new_thread (RT (C::*fun_ptr)(Arg1) const,
1845  typename identity<const C>::type &c,
1846  typename identity<Arg1>::type arg1)
1847  {
1848  return
1849  Thread<RT>
1850  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
1852  }
1853 #endif
1854 
1855 // ----------- thread starters for binary functions
1856 
1863  template <typename RT, typename Arg1, typename Arg2>
1864  inline
1865  Thread<RT>
1866  new_thread (RT (*fun_ptr)(Arg1,Arg2),
1867  typename identity<Arg1>::type arg1,
1868  typename identity<Arg2>::type arg2)
1869  {
1870  return
1871  Thread<RT>
1872  (std_cxx11::bind(fun_ptr,
1875  }
1876 
1877 
1878 
1885  template <typename RT, typename C, typename Arg1, typename Arg2>
1886  inline
1887  Thread<RT>
1888  new_thread (RT (C::*fun_ptr)(Arg1,Arg2),
1889  typename identity<C>::type &c,
1890  typename identity<Arg1>::type arg1,
1891  typename identity<Arg2>::type arg2)
1892  {
1893  return
1894  Thread<RT>
1895  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
1898  }
1899 
1900 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
1901 
1907  template <typename RT, typename C, typename Arg1, typename Arg2>
1908  inline
1909  Thread<RT>
1910  new_thread (RT (C::*fun_ptr)(Arg1,Arg2) const,
1911  typename identity<const C>::type &c,
1912  typename identity<Arg1>::type arg1,
1913  typename identity<Arg2>::type arg2)
1914  {
1915  return
1916  Thread<RT>
1917  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
1920  }
1921 #endif
1922 
1923 // ----------- thread starters for ternary functions
1924 
1931  template <typename RT,
1932  typename Arg1, typename Arg2, typename Arg3>
1933  inline
1934  Thread<RT>
1935  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3),
1936  typename identity<Arg1>::type arg1,
1937  typename identity<Arg2>::type arg2,
1938  typename identity<Arg3>::type arg3)
1939  {
1940  return
1941  Thread<RT>
1942  (std_cxx11::bind(fun_ptr,
1946  }
1947 
1948 
1949 
1956  template <typename RT, typename C,
1957  typename Arg1, typename Arg2, typename Arg3>
1958  inline
1959  Thread<RT>
1960  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3),
1961  typename identity<C>::type &c,
1962  typename identity<Arg1>::type arg1,
1963  typename identity<Arg2>::type arg2,
1964  typename identity<Arg3>::type arg3)
1965  {
1966  return
1967  Thread<RT>
1968  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
1972  }
1973 
1974 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
1975 
1981  template <typename RT, typename C,
1982  typename Arg1, typename Arg2, typename Arg3>
1983  inline
1984  Thread<RT>
1985  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const,
1986  typename identity<const C>::type &c,
1987  typename identity<Arg1>::type arg1,
1988  typename identity<Arg2>::type arg2,
1989  typename identity<Arg3>::type arg3)
1990  {
1991  return
1992  Thread<RT>
1993  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
1997  }
1998 #endif
1999 
2000 
2001 // ----------- thread starters for functions with 4 arguments
2002 
2009  template <typename RT,
2010  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2011  inline
2012  Thread<RT>
2013  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
2014  typename identity<Arg1>::type arg1,
2015  typename identity<Arg2>::type arg2,
2016  typename identity<Arg3>::type arg3,
2017  typename identity<Arg4>::type arg4)
2018  {
2019  return
2020  Thread<RT>
2021  (std_cxx11::bind(fun_ptr,
2026  }
2027 
2028 
2029 
2036  template <typename RT, typename C,
2037  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2038  inline
2039  Thread<RT>
2040  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
2041  typename identity<C>::type &c,
2042  typename identity<Arg1>::type arg1,
2043  typename identity<Arg2>::type arg2,
2044  typename identity<Arg3>::type arg3,
2045  typename identity<Arg4>::type arg4)
2046  {
2047  return
2048  Thread<RT>
2049  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2054  }
2055 
2056 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2057 
2063  template <typename RT, typename C,
2064  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2065  inline
2066  Thread<RT>
2067  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const,
2068  typename identity<const C>::type &c,
2069  typename identity<Arg1>::type arg1,
2070  typename identity<Arg2>::type arg2,
2071  typename identity<Arg3>::type arg3,
2072  typename identity<Arg4>::type arg4)
2073  {
2074  return
2075  Thread<RT>
2076  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2081  }
2082 #endif
2083 
2084 // ----------- thread starters for functions with 5 arguments
2085 
2092  template <typename RT,
2093  typename Arg1, typename Arg2, typename Arg3,
2094  typename Arg4, typename Arg5>
2095  inline
2096  Thread<RT>
2097  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
2098  typename identity<Arg1>::type arg1,
2099  typename identity<Arg2>::type arg2,
2100  typename identity<Arg3>::type arg3,
2101  typename identity<Arg4>::type arg4,
2102  typename identity<Arg5>::type arg5)
2103  {
2104  return
2105  Thread<RT>
2106  (std_cxx11::bind(fun_ptr,
2112  }
2113 
2114 
2115 
2122  template <typename RT, typename C,
2123  typename Arg1, typename Arg2, typename Arg3,
2124  typename Arg4, typename Arg5>
2125  inline
2126  Thread<RT>
2127  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
2128  typename identity<C>::type &c,
2129  typename identity<Arg1>::type arg1,
2130  typename identity<Arg2>::type arg2,
2131  typename identity<Arg3>::type arg3,
2132  typename identity<Arg4>::type arg4,
2133  typename identity<Arg5>::type arg5)
2134  {
2135  return
2136  Thread<RT>
2137  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2143  }
2144 
2145 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2146 
2152  template <typename RT, typename C,
2153  typename Arg1, typename Arg2, typename Arg3,
2154  typename Arg4, typename Arg5>
2155  inline
2156  Thread<RT>
2157  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const,
2158  typename identity<const C>::type &c,
2159  typename identity<Arg1>::type arg1,
2160  typename identity<Arg2>::type arg2,
2161  typename identity<Arg3>::type arg3,
2162  typename identity<Arg4>::type arg4,
2163  typename identity<Arg5>::type arg5)
2164  {
2165  return
2166  Thread<RT>
2167  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2173  }
2174 #endif
2175 
2176 // ----------- thread starters for functions with 6 arguments
2177 
2184  template <typename RT,
2185  typename Arg1, typename Arg2, typename Arg3,
2186  typename Arg4, typename Arg5, typename Arg6>
2187  inline
2188  Thread<RT>
2189  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
2190  typename identity<Arg1>::type arg1,
2191  typename identity<Arg2>::type arg2,
2192  typename identity<Arg3>::type arg3,
2193  typename identity<Arg4>::type arg4,
2194  typename identity<Arg5>::type arg5,
2195  typename identity<Arg6>::type arg6)
2196  {
2197  return
2198  Thread<RT>
2199  (std_cxx11::bind(fun_ptr,
2206  }
2207 
2208 
2209 
2216  template <typename RT, typename C,
2217  typename Arg1, typename Arg2, typename Arg3,
2218  typename Arg4, typename Arg5, typename Arg6>
2219  inline
2220  Thread<RT>
2221  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
2222  typename identity<C>::type &c,
2223  typename identity<Arg1>::type arg1,
2224  typename identity<Arg2>::type arg2,
2225  typename identity<Arg3>::type arg3,
2226  typename identity<Arg4>::type arg4,
2227  typename identity<Arg5>::type arg5,
2228  typename identity<Arg6>::type arg6)
2229  {
2230  return
2231  Thread<RT>
2232  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2239  }
2240 
2241 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2242 
2248  template <typename RT, typename C,
2249  typename Arg1, typename Arg2, typename Arg3,
2250  typename Arg4, typename Arg5, typename Arg6>
2251  inline
2252  Thread<RT>
2253  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const,
2254  typename identity<const C>::type &c,
2255  typename identity<Arg1>::type arg1,
2256  typename identity<Arg2>::type arg2,
2257  typename identity<Arg3>::type arg3,
2258  typename identity<Arg4>::type arg4,
2259  typename identity<Arg5>::type arg5,
2260  typename identity<Arg6>::type arg6)
2261  {
2262  return
2263  Thread<RT>
2264  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2271  }
2272 #endif
2273 
2274 // ----------- thread starters for functions with 7 arguments
2275 
2282  template <typename RT,
2283  typename Arg1, typename Arg2, typename Arg3,
2284  typename Arg4, typename Arg5, typename Arg6,
2285  typename Arg7>
2286  inline
2287  Thread<RT>
2288  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
2289  typename identity<Arg1>::type arg1,
2290  typename identity<Arg2>::type arg2,
2291  typename identity<Arg3>::type arg3,
2292  typename identity<Arg4>::type arg4,
2293  typename identity<Arg5>::type arg5,
2294  typename identity<Arg6>::type arg6,
2295  typename identity<Arg7>::type arg7)
2296  {
2297  return
2298  Thread<RT>
2299  (std_cxx11::bind(fun_ptr,
2307  }
2308 
2309 
2310 
2317  template <typename RT, typename C,
2318  typename Arg1, typename Arg2, typename Arg3,
2319  typename Arg4, typename Arg5, typename Arg6,
2320  typename Arg7>
2321  inline
2322  Thread<RT>
2323  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
2324  typename identity<C>::type &c,
2325  typename identity<Arg1>::type arg1,
2326  typename identity<Arg2>::type arg2,
2327  typename identity<Arg3>::type arg3,
2328  typename identity<Arg4>::type arg4,
2329  typename identity<Arg5>::type arg5,
2330  typename identity<Arg6>::type arg6,
2331  typename identity<Arg7>::type arg7)
2332  {
2333  return
2334  Thread<RT>
2335  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2343  }
2344 
2345 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2346 
2352  template <typename RT, typename C,
2353  typename Arg1, typename Arg2, typename Arg3,
2354  typename Arg4, typename Arg5, typename Arg6,
2355  typename Arg7>
2356  inline
2357  Thread<RT>
2358  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const,
2359  typename identity<const C>::type &c,
2360  typename identity<Arg1>::type arg1,
2361  typename identity<Arg2>::type arg2,
2362  typename identity<Arg3>::type arg3,
2363  typename identity<Arg4>::type arg4,
2364  typename identity<Arg5>::type arg5,
2365  typename identity<Arg6>::type arg6,
2366  typename identity<Arg7>::type arg7)
2367  {
2368  return
2369  Thread<RT>
2370  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2378  }
2379 #endif
2380 
2381 // ----------- thread starters for functions with 8 arguments
2382 
2389  template <typename RT,
2390  typename Arg1, typename Arg2, typename Arg3,
2391  typename Arg4, typename Arg5, typename Arg6,
2392  typename Arg7, typename Arg8>
2393  inline
2394  Thread<RT>
2395  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2396  Arg6,Arg7,Arg8),
2397  typename identity<Arg1>::type arg1,
2398  typename identity<Arg2>::type arg2,
2399  typename identity<Arg3>::type arg3,
2400  typename identity<Arg4>::type arg4,
2401  typename identity<Arg5>::type arg5,
2402  typename identity<Arg6>::type arg6,
2403  typename identity<Arg7>::type arg7,
2404  typename identity<Arg8>::type arg8)
2405  {
2406  return
2407  Thread<RT>
2408  (std_cxx11::bind(fun_ptr,
2417  }
2418 
2419 
2420 
2427  template <typename RT, typename C,
2428  typename Arg1, typename Arg2, typename Arg3,
2429  typename Arg4, typename Arg5, typename Arg6,
2430  typename Arg7, typename Arg8>
2431  inline
2432  Thread<RT>
2433  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2434  Arg6,Arg7,Arg8),
2435  typename identity<C>::type &c,
2436  typename identity<Arg1>::type arg1,
2437  typename identity<Arg2>::type arg2,
2438  typename identity<Arg3>::type arg3,
2439  typename identity<Arg4>::type arg4,
2440  typename identity<Arg5>::type arg5,
2441  typename identity<Arg6>::type arg6,
2442  typename identity<Arg7>::type arg7,
2443  typename identity<Arg8>::type arg8)
2444  {
2445  return
2446  Thread<RT>
2447  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2456  }
2457 
2458 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2459 
2465  template <typename RT, typename C,
2466  typename Arg1, typename Arg2, typename Arg3,
2467  typename Arg4, typename Arg5, typename Arg6,
2468  typename Arg7, typename Arg8>
2469  inline
2470  Thread<RT>
2471  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2472  Arg6,Arg7,Arg8) const,
2473  typename identity<const C>::type &c,
2474  typename identity<Arg1>::type arg1,
2475  typename identity<Arg2>::type arg2,
2476  typename identity<Arg3>::type arg3,
2477  typename identity<Arg4>::type arg4,
2478  typename identity<Arg5>::type arg5,
2479  typename identity<Arg6>::type arg6,
2480  typename identity<Arg7>::type arg7,
2481  typename identity<Arg8>::type arg8)
2482  {
2483  return
2484  Thread<RT>
2485  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2494  }
2495 #endif
2496 
2497 // ----------- thread starters for functions with 9 arguments
2498 
2505  template <typename RT,
2506  typename Arg1, typename Arg2, typename Arg3,
2507  typename Arg4, typename Arg5, typename Arg6,
2508  typename Arg7, typename Arg8, typename Arg9>
2509  inline
2510  Thread<RT>
2511  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2512  Arg6,Arg7,Arg8,Arg9),
2513  typename identity<Arg1>::type arg1,
2514  typename identity<Arg2>::type arg2,
2515  typename identity<Arg3>::type arg3,
2516  typename identity<Arg4>::type arg4,
2517  typename identity<Arg5>::type arg5,
2518  typename identity<Arg6>::type arg6,
2519  typename identity<Arg7>::type arg7,
2520  typename identity<Arg8>::type arg8,
2521  typename identity<Arg9>::type arg9)
2522  {
2523  return
2524  Thread<RT>
2525  (std_cxx11::bind(fun_ptr,
2535  }
2536 
2537 
2538 
2545  template <typename RT, typename C,
2546  typename Arg1, typename Arg2, typename Arg3,
2547  typename Arg4, typename Arg5, typename Arg6,
2548  typename Arg7, typename Arg8, typename Arg9>
2549  inline
2550  Thread<RT>
2551  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2552  Arg6,Arg7,Arg8,Arg9),
2553  typename identity<C>::type &c,
2554  typename identity<Arg1>::type arg1,
2555  typename identity<Arg2>::type arg2,
2556  typename identity<Arg3>::type arg3,
2557  typename identity<Arg4>::type arg4,
2558  typename identity<Arg5>::type arg5,
2559  typename identity<Arg6>::type arg6,
2560  typename identity<Arg7>::type arg7,
2561  typename identity<Arg8>::type arg8,
2562  typename identity<Arg9>::type arg9)
2563  {
2564  return
2565  Thread<RT>
2566  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2576  }
2577 
2578 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2579 
2585  template <typename RT, typename C,
2586  typename Arg1, typename Arg2, typename Arg3,
2587  typename Arg4, typename Arg5, typename Arg6,
2588  typename Arg7, typename Arg8, typename Arg9>
2589  inline
2590  Thread<RT>
2591  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2592  Arg6,Arg7,Arg8,Arg9) const,
2593  typename identity<const C>::type &c,
2594  typename identity<Arg1>::type arg1,
2595  typename identity<Arg2>::type arg2,
2596  typename identity<Arg3>::type arg3,
2597  typename identity<Arg4>::type arg4,
2598  typename identity<Arg5>::type arg5,
2599  typename identity<Arg6>::type arg6,
2600  typename identity<Arg7>::type arg7,
2601  typename identity<Arg8>::type arg8,
2602  typename identity<Arg9>::type arg9)
2603  {
2604  return
2605  Thread<RT>
2606  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2616  }
2617 #endif
2618 
2619 // ------------------------ ThreadGroup -------------------------------------
2620 
2629  template <typename RT = void>
2631  {
2632  public:
2637  {
2638  threads.push_back (t);
2639  return *this;
2640  }
2641 
2648  void join_all () const
2649  {
2650  for (typename std::list<Thread<RT> >::const_iterator
2651  t=threads.begin(); t!=threads.end(); ++t)
2652  t->join ();
2653  }
2654 
2655  private:
2659  std::list<Thread<RT> > threads;
2660  };
2661 
2662 
2663  template <typename> class Task;
2664 
2665 
2666  namespace internal
2667  {
2668 #ifdef DEAL_II_WITH_THREADS
2669 
2670  template <typename> struct TaskDescriptor;
2671 
2675  template <typename RT>
2676  struct TaskEntryPoint : public tbb::task
2677  {
2678  TaskEntryPoint (TaskDescriptor<RT> &task_descriptor)
2679  :
2680  task_descriptor (task_descriptor)
2681  {}
2682 
2683  virtual tbb::task *execute ()
2684  {
2685  // call the function object and put the return value into the
2686  // proper place
2687  try
2688  {
2689  call (task_descriptor.function, task_descriptor.ret_val);
2690  }
2691  catch (const std::exception &exc)
2692  {
2693  internal::handle_std_exception (exc);
2694  }
2695  catch (...)
2696  {
2697  internal::handle_unknown_exception ();
2698  }
2699  return 0;
2700  }
2701 
2705  TaskDescriptor<RT> &task_descriptor;
2706  };
2707 
2729  template <typename RT>
2730  struct TaskDescriptor
2731  {
2732  private:
2736  std_cxx11::function<RT ()> function;
2737 
2746  tbb::task *task;
2747 
2751  return_value<RT> ret_val;
2752 
2756  bool task_is_done;
2757 
2758  public:
2759 
2763  TaskDescriptor (const std_cxx11::function<RT ()> &function);
2764 
2770  TaskDescriptor ();
2771 
2776  TaskDescriptor (const TaskDescriptor &);
2777 
2781  ~TaskDescriptor ();
2782 
2789  void queue_task ();
2790 
2796  void join ();
2797 
2798 
2799  template <typename> friend struct TaskEntryPoint;
2800  friend class ::Threads::Task<RT>;
2801  };
2802 
2803 
2804 
2805  template <typename RT>
2806  inline
2807  TaskDescriptor<RT>::TaskDescriptor (const std_cxx11::function<RT ()> &function)
2808  :
2809  function (function),
2810  task_is_done (false)
2811  {}
2812 
2813 
2814  template <typename RT>
2815  inline
2816  void
2817  TaskDescriptor<RT>::queue_task ()
2818  {
2819  // use the pattern described in the TBB book on pages 230/231
2820  // ("Start a large task in parallel with the main program")
2821  task = new (tbb::task::allocate_root()) tbb::empty_task;
2822  task->set_ref_count (2);
2823 
2824  tbb::task *worker = new (task->allocate_child()) TaskEntryPoint<RT>(*this);
2825  task->spawn (*worker);
2826  }
2827 
2828 
2829 
2830  template <typename RT>
2831  TaskDescriptor<RT>::TaskDescriptor ()
2832  {
2833  Assert (false, ExcInternalError());
2834  }
2835 
2836 
2837 
2838  template <typename RT>
2839  TaskDescriptor<RT>::TaskDescriptor (const TaskDescriptor &)
2840  {
2841  Assert (false, ExcInternalError());
2842  }
2843 
2844 
2845 
2846  template <typename RT>
2847  inline
2848  TaskDescriptor<RT>::~TaskDescriptor ()
2849  {
2850  // wait for the task to complete for sure
2851  join ();
2852 
2853  // now destroy the empty task structure. the book recommends to
2854  // spawn it as well and let the scheduler destroy the object
2855  // when done, but this has the disadvantage that the scheduler
2856  // may not get to actually finishing the task before it goes out
2857  // of scope (at the end of the program, or if a thread is done
2858  // on which it was run) and then we would get a hard-to-decipher
2859  // warning about unfinished tasks when the scheduler "goes out
2860  // of the arena". rather, let's explicitly destroy the empty
2861  // task object. before that, make sure that the task has been
2862  // shut down, expressed by a zero reference count
2863  Assert (task != 0, ExcInternalError());
2864  Assert (task->ref_count()==0, ExcInternalError());
2865  task->destroy (*task);
2866  }
2867 
2868 
2869  template <typename RT>
2870  inline
2871  void
2872  TaskDescriptor<RT>::join ()
2873  {
2874  // if the task is already done, just return. this makes sure we
2875  // call tbb::Task::wait_for_all() exactly once, as required by
2876  // TBB. we could also get the reference count of task for doing
2877  // this, but that is usually slower. note that this does not
2878  // work when the thread calling this function is not the same as
2879  // the one that initialized the task.
2880  //
2881  // TODO: can we assert that no other thread tries to end the
2882  // task?
2883  if (task_is_done == true)
2884  return;
2885 
2886  // let TBB wait for the task to complete.
2887  task_is_done = true;
2888  task->wait_for_all();
2889  }
2890 
2891 
2892 
2893 #else // no threading enabled
2894 
2899  template <typename RT>
2900  struct TaskDescriptor
2901  {
2905  return_value<RT> ret_val;
2906 
2911  TaskDescriptor (const std_cxx11::function<RT ()> &function)
2912  {
2913  call (function, ret_val);
2914  }
2915 
2920  static void join () {}
2921 
2926  static void queue_task () {}
2927  };
2928 
2929 #endif
2930 
2931  }
2932 
2933 
2934 
2945  template <typename RT = void>
2946  class Task
2947  {
2948  public:
2956  Task (const std_cxx11::function<RT ()> &function_object)
2957  {
2958  // create a task descriptor and tell it to queue itself up with
2959  // the scheduling system
2960  task_descriptor.reset (new internal::TaskDescriptor<RT>(function_object));
2961  task_descriptor->queue_task ();
2962  }
2963 
2964 
2971  Task (const Task<RT> &t)
2972  :
2974  {}
2975 
2976 
2985  Task () {}
2986 
2998  void join () const
2999  {
3000  AssertThrow (joinable(), ExcNoTask());
3001  task_descriptor->join ();
3002  }
3003 
3016  bool joinable () const
3017  {
3018  return (task_descriptor !=
3019  std_cxx11::shared_ptr<internal::TaskDescriptor<RT> >());
3020  }
3021 
3022 
3034  {
3035  join ();
3036  return task_descriptor->ret_val.get();
3037  }
3038 
3039 
3045  bool operator == (const Task &t)
3046  {
3047  AssertThrow (joinable(), ExcNoTask());
3048  return task_descriptor == t.task_descriptor;
3049  }
3050 
3059  DeclExceptionMsg (ExcNoTask,
3060  "The current object is not associated with a task that "
3061  "can be joined. It may have been detached, or you "
3062  "may have already joined it in the past.");
3064  private:
3070  std_cxx11::shared_ptr<internal::TaskDescriptor<RT> > task_descriptor;
3071  };
3072 
3073 
3074 
3083  template <typename RT>
3084  inline
3085  Task<RT>
3086  new_task (const std_cxx11::function<RT ()> &function)
3087  {
3088  return Task<RT>(function);
3089  }
3090 
3097  template <typename RT>
3098  inline
3099  Task<RT>
3100  new_task (RT (*fun_ptr)())
3101  {
3102  return new_task<RT>(std_cxx11::function<RT ()>(fun_ptr));
3103  }
3104 
3105 
3112  template <typename RT, typename C>
3113  inline
3114  Task<RT>
3115  new_task (RT (C::*fun_ptr)(),
3116  typename identity<C>::type &c)
3117  {
3118  return
3119  new_task<RT>
3120  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c)));
3121  }
3122 
3123 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3124 
3130  template <typename RT, typename C>
3131  inline
3132  Task<RT>
3133  new_task (RT (C::*fun_ptr)() const,
3134  const typename identity<C>::type &c)
3135  {
3136  return
3137  new_task<RT>
3138  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c)));
3139  }
3140 #endif
3141 
3142 
3143 
3144 // ----------- thread starters for unary functions
3145 
3152  template <typename RT, typename Arg1>
3153  inline
3154  Task<RT>
3155  new_task (RT (*fun_ptr)(Arg1),
3156  typename identity<Arg1>::type arg1)
3157  {
3158  return
3159  new_task<RT>
3160  (std_cxx11::bind(fun_ptr,
3162  }
3163 
3164 
3165 
3172  template <typename RT, typename C, typename Arg1>
3173  inline
3174  Task<RT>
3175  new_task (RT (C::*fun_ptr)(Arg1),
3176  typename identity<C>::type &c,
3177  typename identity<Arg1>::type arg1)
3178  {
3179  return
3180  new_task<RT>
3181  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3183  }
3184 
3185 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3186 
3192  template <typename RT, typename C, typename Arg1>
3193  inline
3194  Task<RT>
3195  new_task (RT (C::*fun_ptr)(Arg1) const,
3196  typename identity<const C>::type &c,
3197  typename identity<Arg1>::type arg1)
3198  {
3199  return
3200  new_task<RT>
3201  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3203  }
3204 #endif
3205 
3206 // ----------- thread starters for binary functions
3207 
3214  template <typename RT, typename Arg1, typename Arg2>
3215  inline
3216  Task<RT>
3217  new_task (RT (*fun_ptr)(Arg1,Arg2),
3218  typename identity<Arg1>::type arg1,
3219  typename identity<Arg2>::type arg2)
3220  {
3221  return
3222  new_task<RT>
3223  (std_cxx11::bind(fun_ptr,
3226  }
3227 
3228 
3229 
3236  template <typename RT, typename C, typename Arg1, typename Arg2>
3237  inline
3238  Task<RT>
3239  new_task (RT (C::*fun_ptr)(Arg1,Arg2),
3240  typename identity<C>::type &c,
3241  typename identity<Arg1>::type arg1,
3242  typename identity<Arg2>::type arg2)
3243  {
3244  return
3245  new_task<RT>
3246  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3249  }
3250 
3251 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3252 
3258  template <typename RT, typename C, typename Arg1, typename Arg2>
3259  inline
3260  Task<RT>
3261  new_task (RT (C::*fun_ptr)(Arg1,Arg2) const,
3262  typename identity<const C>::type &c,
3263  typename identity<Arg1>::type arg1,
3264  typename identity<Arg2>::type arg2)
3265  {
3266  return
3267  new_task<RT>
3268  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3271  }
3272 #endif
3273 
3274 // ----------- thread starters for ternary functions
3275 
3282  template <typename RT,
3283  typename Arg1, typename Arg2, typename Arg3>
3284  inline
3285  Task<RT>
3286  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3),
3287  typename identity<Arg1>::type arg1,
3288  typename identity<Arg2>::type arg2,
3289  typename identity<Arg3>::type arg3)
3290  {
3291  return
3292  new_task<RT>
3293  (std_cxx11::bind(fun_ptr,
3297  }
3298 
3299 
3300 
3307  template <typename RT, typename C,
3308  typename Arg1, typename Arg2, typename Arg3>
3309  inline
3310  Task<RT>
3311  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3),
3312  typename identity<C>::type &c,
3313  typename identity<Arg1>::type arg1,
3314  typename identity<Arg2>::type arg2,
3315  typename identity<Arg3>::type arg3)
3316  {
3317  return
3318  new_task<RT>
3319  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3323  }
3324 
3325 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3326 
3332  template <typename RT, typename C,
3333  typename Arg1, typename Arg2, typename Arg3>
3334  inline
3335  Task<RT>
3336  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const,
3337  typename identity<const C>::type &c,
3338  typename identity<Arg1>::type arg1,
3339  typename identity<Arg2>::type arg2,
3340  typename identity<Arg3>::type arg3)
3341  {
3342  return
3343  new_task<RT>
3344  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3348  }
3349 #endif
3350 
3351 
3352 // ----------- thread starters for functions with 4 arguments
3353 
3360  template <typename RT,
3361  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3362  inline
3363  Task<RT>
3364  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
3365  typename identity<Arg1>::type arg1,
3366  typename identity<Arg2>::type arg2,
3367  typename identity<Arg3>::type arg3,
3368  typename identity<Arg4>::type arg4)
3369  {
3370  return
3371  new_task<RT>
3372  (std_cxx11::bind(fun_ptr,
3377  }
3378 
3379 
3380 
3387  template <typename RT, typename C,
3388  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3389  inline
3390  Task<RT>
3391  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
3392  typename identity<C>::type &c,
3393  typename identity<Arg1>::type arg1,
3394  typename identity<Arg2>::type arg2,
3395  typename identity<Arg3>::type arg3,
3396  typename identity<Arg4>::type arg4)
3397  {
3398  return
3399  new_task<RT>
3400  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3405  }
3406 
3407 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3408 
3414  template <typename RT, typename C,
3415  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3416  inline
3417  Task<RT>
3418  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const,
3419  typename identity<const C>::type &c,
3420  typename identity<Arg1>::type arg1,
3421  typename identity<Arg2>::type arg2,
3422  typename identity<Arg3>::type arg3,
3423  typename identity<Arg4>::type arg4)
3424  {
3425  return
3426  new_task<RT>
3427  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3432  }
3433 #endif
3434 
3435 // ----------- thread starters for functions with 5 arguments
3436 
3443  template <typename RT,
3444  typename Arg1, typename Arg2, typename Arg3,
3445  typename Arg4, typename Arg5>
3446  inline
3447  Task<RT>
3448  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
3449  typename identity<Arg1>::type arg1,
3450  typename identity<Arg2>::type arg2,
3451  typename identity<Arg3>::type arg3,
3452  typename identity<Arg4>::type arg4,
3453  typename identity<Arg5>::type arg5)
3454  {
3455  return
3456  new_task<RT>
3457  (std_cxx11::bind(fun_ptr,
3463  }
3464 
3465 
3466 
3473  template <typename RT, typename C,
3474  typename Arg1, typename Arg2, typename Arg3,
3475  typename Arg4, typename Arg5>
3476  inline
3477  Task<RT>
3478  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
3479  typename identity<C>::type &c,
3480  typename identity<Arg1>::type arg1,
3481  typename identity<Arg2>::type arg2,
3482  typename identity<Arg3>::type arg3,
3483  typename identity<Arg4>::type arg4,
3484  typename identity<Arg5>::type arg5)
3485  {
3486  return
3487  new_task<RT>
3488  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3494  }
3495 
3496 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3497 
3503  template <typename RT, typename C,
3504  typename Arg1, typename Arg2, typename Arg3,
3505  typename Arg4, typename Arg5>
3506  inline
3507  Task<RT>
3508  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const,
3509  typename identity<const C>::type &c,
3510  typename identity<Arg1>::type arg1,
3511  typename identity<Arg2>::type arg2,
3512  typename identity<Arg3>::type arg3,
3513  typename identity<Arg4>::type arg4,
3514  typename identity<Arg5>::type arg5)
3515  {
3516  return
3517  new_task<RT>
3518  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3524  }
3525 #endif
3526 
3527 // ----------- thread starters for functions with 6 arguments
3528 
3535  template <typename RT,
3536  typename Arg1, typename Arg2, typename Arg3,
3537  typename Arg4, typename Arg5, typename Arg6>
3538  inline
3539  Task<RT>
3540  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
3541  typename identity<Arg1>::type arg1,
3542  typename identity<Arg2>::type arg2,
3543  typename identity<Arg3>::type arg3,
3544  typename identity<Arg4>::type arg4,
3545  typename identity<Arg5>::type arg5,
3546  typename identity<Arg6>::type arg6)
3547  {
3548  return
3549  new_task<RT>
3550  (std_cxx11::bind(fun_ptr,
3557  }
3558 
3559 
3560 
3567  template <typename RT, typename C,
3568  typename Arg1, typename Arg2, typename Arg3,
3569  typename Arg4, typename Arg5, typename Arg6>
3570  inline
3571  Task<RT>
3572  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
3573  typename identity<C>::type &c,
3574  typename identity<Arg1>::type arg1,
3575  typename identity<Arg2>::type arg2,
3576  typename identity<Arg3>::type arg3,
3577  typename identity<Arg4>::type arg4,
3578  typename identity<Arg5>::type arg5,
3579  typename identity<Arg6>::type arg6)
3580  {
3581  return
3582  new_task<RT>
3583  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3590  }
3591 
3592 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3593 
3599  template <typename RT, typename C,
3600  typename Arg1, typename Arg2, typename Arg3,
3601  typename Arg4, typename Arg5, typename Arg6>
3602  inline
3603  Task<RT>
3604  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const,
3605  typename identity<const C>::type &c,
3606  typename identity<Arg1>::type arg1,
3607  typename identity<Arg2>::type arg2,
3608  typename identity<Arg3>::type arg3,
3609  typename identity<Arg4>::type arg4,
3610  typename identity<Arg5>::type arg5,
3611  typename identity<Arg6>::type arg6)
3612  {
3613  return
3614  new_task<RT>
3615  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3622  }
3623 #endif
3624 
3625 // ----------- thread starters for functions with 7 arguments
3626 
3633  template <typename RT,
3634  typename Arg1, typename Arg2, typename Arg3,
3635  typename Arg4, typename Arg5, typename Arg6,
3636  typename Arg7>
3637  inline
3638  Task<RT>
3639  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
3640  typename identity<Arg1>::type arg1,
3641  typename identity<Arg2>::type arg2,
3642  typename identity<Arg3>::type arg3,
3643  typename identity<Arg4>::type arg4,
3644  typename identity<Arg5>::type arg5,
3645  typename identity<Arg6>::type arg6,
3646  typename identity<Arg7>::type arg7)
3647  {
3648  return
3649  new_task<RT>
3650  (std_cxx11::bind(fun_ptr,
3658  }
3659 
3660 
3661 
3668  template <typename RT, typename C,
3669  typename Arg1, typename Arg2, typename Arg3,
3670  typename Arg4, typename Arg5, typename Arg6,
3671  typename Arg7>
3672  inline
3673  Task<RT>
3674  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
3675  typename identity<C>::type &c,
3676  typename identity<Arg1>::type arg1,
3677  typename identity<Arg2>::type arg2,
3678  typename identity<Arg3>::type arg3,
3679  typename identity<Arg4>::type arg4,
3680  typename identity<Arg5>::type arg5,
3681  typename identity<Arg6>::type arg6,
3682  typename identity<Arg7>::type arg7)
3683  {
3684  return
3685  new_task<RT>
3686  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3694  }
3695 
3696 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3697 
3703  template <typename RT, typename C,
3704  typename Arg1, typename Arg2, typename Arg3,
3705  typename Arg4, typename Arg5, typename Arg6,
3706  typename Arg7>
3707  inline
3708  Task<RT>
3709  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const,
3710  typename identity<const C>::type &c,
3711  typename identity<Arg1>::type arg1,
3712  typename identity<Arg2>::type arg2,
3713  typename identity<Arg3>::type arg3,
3714  typename identity<Arg4>::type arg4,
3715  typename identity<Arg5>::type arg5,
3716  typename identity<Arg6>::type arg6,
3717  typename identity<Arg7>::type arg7)
3718  {
3719  return
3720  new_task<RT>
3721  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3729  }
3730 #endif
3731 
3732 // ----------- thread starters for functions with 8 arguments
3733 
3740  template <typename RT,
3741  typename Arg1, typename Arg2, typename Arg3,
3742  typename Arg4, typename Arg5, typename Arg6,
3743  typename Arg7, typename Arg8>
3744  inline
3745  Task<RT>
3746  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3747  Arg6,Arg7,Arg8),
3748  typename identity<Arg1>::type arg1,
3749  typename identity<Arg2>::type arg2,
3750  typename identity<Arg3>::type arg3,
3751  typename identity<Arg4>::type arg4,
3752  typename identity<Arg5>::type arg5,
3753  typename identity<Arg6>::type arg6,
3754  typename identity<Arg7>::type arg7,
3755  typename identity<Arg8>::type arg8)
3756  {
3757  return
3758  new_task<RT>
3759  (std_cxx11::bind(fun_ptr,
3768  }
3769 
3770 
3771 
3778  template <typename RT, typename C,
3779  typename Arg1, typename Arg2, typename Arg3,
3780  typename Arg4, typename Arg5, typename Arg6,
3781  typename Arg7, typename Arg8>
3782  inline
3783  Task<RT>
3784  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3785  Arg6,Arg7,Arg8),
3786  typename identity<C>::type &c,
3787  typename identity<Arg1>::type arg1,
3788  typename identity<Arg2>::type arg2,
3789  typename identity<Arg3>::type arg3,
3790  typename identity<Arg4>::type arg4,
3791  typename identity<Arg5>::type arg5,
3792  typename identity<Arg6>::type arg6,
3793  typename identity<Arg7>::type arg7,
3794  typename identity<Arg8>::type arg8)
3795  {
3796  return
3797  new_task<RT>
3798  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3807  }
3808 
3809 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3810 
3816  template <typename RT, typename C,
3817  typename Arg1, typename Arg2, typename Arg3,
3818  typename Arg4, typename Arg5, typename Arg6,
3819  typename Arg7, typename Arg8>
3820  inline
3821  Task<RT>
3822  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3823  Arg6,Arg7,Arg8) const,
3824  typename identity<const C>::type &c,
3825  typename identity<Arg1>::type arg1,
3826  typename identity<Arg2>::type arg2,
3827  typename identity<Arg3>::type arg3,
3828  typename identity<Arg4>::type arg4,
3829  typename identity<Arg5>::type arg5,
3830  typename identity<Arg6>::type arg6,
3831  typename identity<Arg7>::type arg7,
3832  typename identity<Arg8>::type arg8)
3833  {
3834  return
3835  new_task<RT>
3836  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3845  }
3846 #endif
3847 
3848 // ----------- thread starters for functions with 9 arguments
3849 
3856  template <typename RT,
3857  typename Arg1, typename Arg2, typename Arg3,
3858  typename Arg4, typename Arg5, typename Arg6,
3859  typename Arg7, typename Arg8, typename Arg9>
3860  inline
3861  Task<RT>
3862  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3863  Arg6,Arg7,Arg8,Arg9),
3864  typename identity<Arg1>::type arg1,
3865  typename identity<Arg2>::type arg2,
3866  typename identity<Arg3>::type arg3,
3867  typename identity<Arg4>::type arg4,
3868  typename identity<Arg5>::type arg5,
3869  typename identity<Arg6>::type arg6,
3870  typename identity<Arg7>::type arg7,
3871  typename identity<Arg8>::type arg8,
3872  typename identity<Arg9>::type arg9)
3873  {
3874  return
3875  new_task<RT>
3876  (std_cxx11::bind(fun_ptr,
3886  }
3887 
3888 
3889 
3896  template <typename RT, typename C,
3897  typename Arg1, typename Arg2, typename Arg3,
3898  typename Arg4, typename Arg5, typename Arg6,
3899  typename Arg7, typename Arg8, typename Arg9>
3900  inline
3901  Task<RT>
3902  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3903  Arg6,Arg7,Arg8,Arg9),
3904  typename identity<C>::type &c,
3905  typename identity<Arg1>::type arg1,
3906  typename identity<Arg2>::type arg2,
3907  typename identity<Arg3>::type arg3,
3908  typename identity<Arg4>::type arg4,
3909  typename identity<Arg5>::type arg5,
3910  typename identity<Arg6>::type arg6,
3911  typename identity<Arg7>::type arg7,
3912  typename identity<Arg8>::type arg8,
3913  typename identity<Arg9>::type arg9)
3914  {
3915  return
3916  new_task<RT>
3917  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3927  }
3928 
3929 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3930 
3936  template <typename RT, typename C,
3937  typename Arg1, typename Arg2, typename Arg3,
3938  typename Arg4, typename Arg5, typename Arg6,
3939  typename Arg7, typename Arg8, typename Arg9>
3940  inline
3941  Task<RT>
3942  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3943  Arg6,Arg7,Arg8,Arg9) const,
3944  typename identity<const C>::type &c,
3945  typename identity<Arg1>::type arg1,
3946  typename identity<Arg2>::type arg2,
3947  typename identity<Arg3>::type arg3,
3948  typename identity<Arg4>::type arg4,
3949  typename identity<Arg5>::type arg5,
3950  typename identity<Arg6>::type arg6,
3951  typename identity<Arg7>::type arg7,
3952  typename identity<Arg8>::type arg8,
3953  typename identity<Arg9>::type arg9)
3954  {
3955  return
3956  new_task<RT>
3957  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3967  }
3968 #endif
3969 
3970 
3971 // ------------------------ TaskGroup -------------------------------------
3972 
3986  template <typename RT = void>
3988  {
3989  public:
3994  {
3995  tasks.push_back (t);
3996  return *this;
3997  }
3998 
4005  void join_all () const
4006  {
4007  for (typename std::list<Task<RT> >::const_iterator
4008  t=tasks.begin(); t!=tasks.end(); ++t)
4009  t->join ();
4010  }
4011 
4012  private:
4016  std::list<Task<RT> > tasks;
4017  };
4018 
4019 } // end of implementation of namespace Threads
4020 
4026 //---------------------------------------------------------------------------
4027 DEAL_II_NAMESPACE_CLOSE
4028 // end of #ifndef dealii__thread_management_h
4029 #endif
4030 //---------------------------------------------------------------------------
std_cxx11::condition_variable condition_variable
Task(const std_cxx11::function< RT()> &function_object)
bool valid() const
std::vector< std::pair< ForwardIterator, ForwardIterator > > split_range(const ForwardIterator &begin, const ForwardIterator &end, const unsigned int n_intervals)
unsigned int this_thread_id()
void start(const std_cxx11::function< RT()> &function)
Thread(const Thread< RT > &t)
TaskDescriptor< RT > & task_descriptor
Mutex(const Mutex &)
std::list< Task< RT > > tasks
Thread(const std_cxx11::function< RT()> &function)
static void thread_entry_point(const std_cxx11::function< RT()> function, std_cxx11::shared_ptr< return_value< RT > > ret_val)
#define AssertThrow(cond, exc)
Definition: exceptions.h:358
PosixThreadBarrier(const unsigned int count, const char *name=0, void *arg=0)
std::vector< std::pair< unsigned int, unsigned int > > split_interval(const unsigned int begin, const unsigned int end, const unsigned int n_intervals)
DummyBarrier(const unsigned int count, const char *name=0, void *arg=0)
void join() const
void wait(DummyThreadMutex &) const
Thread< RT > new_thread(const std_cxx11::function< RT()> &function)
#define Assert(cond, exc)
Definition: exceptions.h:294
void join() const
unsigned int n_existing_threads()
bool operator==(const Thread &t)
bool operator==(const Task &t)
std_cxx11::shared_ptr< internal::ThreadDescriptor< RT > > thread_descriptor
DeclExceptionMsg(ExcNoTask,"The current object is not associated with a task that ""can be joined. It may have been detached, or you ""may have already joined it in the past.")
TaskGroup & operator+=(const Task< RT > &t)
ThreadGroup & operator+=(const Thread< RT > &t)
std_cxx11::shared_ptr< return_value< RT > > ret_val
PosixThreadBarrier Barrier
Task(const Task< RT > &t)
bool joinable() const
DeclException1(ExcBarrierSizeNotUseful, int,<< "In single-thread mode, barrier sizes other than 1 are not "<< "useful. You gave "<< arg1<< ".")
std_cxx11::shared_ptr< internal::TaskDescriptor< RT > > task_descriptor
Task< RT > new_task(const std_cxx11::function< RT()> &function)
std::list< Thread< RT > > threads
std_cxx11::mutex mutex