Reference documentation for deal.II version 8.5.1
thread_management.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2000 - 2017 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 # include <tbb/tbb_stddef.h>
46 #endif
47 
48 
49 
50 DEAL_II_NAMESPACE_OPEN
51 
54 
55 
63 namespace Threads
64 {
79  {
80  public:
95  class ScopedLock
96  {
97  public:
103 
109  };
110 
115  inline void acquire () const {}
116 
121  inline void release () const {}
122  };
123 
124 
125 
144  {
145  public:
151  inline void signal () const {}
152 
158  inline void broadcast () const {}
159 
167  inline void wait (DummyThreadMutex &) const {}
168  };
169 
170 
171 
188  {
189  public:
195  DummyBarrier (const unsigned int count,
196  const char *name = 0,
197  void *arg = 0);
198 
203  inline int wait () const
204  {
205  return 0;
206  }
207 
211  inline void dump () const {}
212 
222  int,
223  << "In single-thread mode, barrier sizes other than 1 are not "
224  << "useful. You gave " << arg1 << ".");
225 
227  };
228 
229 
230 #ifdef DEAL_II_WITH_THREADS
231 
248  class Mutex
249  {
250  public:
266  {
267  public:
272  {
273  mutex.acquire();
274  }
275 
281  {
282  mutex.release ();
283  }
284 
285  private:
290  };
291 
295  Mutex ()
296  {}
297 
302  Mutex (const Mutex &)
303  :
304  mutex()
305  {}
306 
307 
313  {
314  return *this;
315  }
316 
317 
321  inline void acquire ()
322  {
323  mutex.lock();
324  }
325 
329  inline void release ()
330  {
331  mutex.unlock();
332  }
333 
334  private:
338  std_cxx11::mutex mutex;
339 
344  friend class ConditionVariable;
345  };
346 
347 
355  {
356  public:
361  inline void signal ()
362  {
363  condition_variable.notify_one();
364  }
365 
370  inline void broadcast ()
371  {
372  condition_variable.notify_all();
373  }
374 
384  inline void wait (Mutex &mutex)
385  {
386  std_cxx11::unique_lock<std_cxx11::mutex> lock(mutex.mutex,
387  std_cxx11::adopt_lock);
388  condition_variable.wait (lock);
389  }
390 
391  private:
395  std_cxx11::condition_variable condition_variable;
396  };
397 
398 
415  {
416  public:
420  PosixThreadBarrier (const unsigned int count,
421  const char *name = 0,
422  void *arg = 0);
423 
428 
435  int wait ();
436 
437  private:
442 #ifndef DEAL_II_USE_MT_POSIX_NO_BARRIERS
443  pthread_barrier_t barrier;
444 #else
445  unsigned int count;
446 #endif
447  };
448 
449 
455 
456 #else
457 
462  typedef DummyThreadMutex Mutex;
463 
470 
476  typedef DummyBarrier Barrier;
477 #endif
478 
479 }
480 
481 
482 namespace Threads
483 {
484 
514  unsigned int n_existing_threads ();
515 
527  unsigned int this_thread_id ();
528 
543  template <typename ForwardIterator>
544  std::vector<std::pair<ForwardIterator,ForwardIterator> >
545  split_range (const ForwardIterator &begin,
546  const ForwardIterator &end,
547  const unsigned int n_intervals);
548 
557  std::vector<std::pair<unsigned int,unsigned int> >
558  split_interval (const unsigned int begin,
559  const unsigned int end,
560  const unsigned int n_intervals);
561 
573  namespace internal
574  {
590  void handle_std_exception (const std::exception &exc);
591 
599  void handle_unknown_exception ();
600 
608  void register_thread ();
609 
617  void deregister_thread ();
618  }
619 
624 } // end declarations of namespace Threads
625 
626 /* ----------- implementation of functions in namespace Threads ---------- */
627 #ifndef DOXYGEN
628 namespace Threads
629 {
630  template <typename ForwardIterator>
631  std::vector<std::pair<ForwardIterator,ForwardIterator> >
632  split_range (const ForwardIterator &begin,
633  const ForwardIterator &end,
634  const unsigned int n_intervals)
635  {
636  typedef std::pair<ForwardIterator,ForwardIterator> IteratorPair;
637 
638  // in non-multithreaded mode, we often have the case that this
639  // function is called with n_intervals==1, so have a shortcut here
640  // to handle that case efficiently
641 
642  if (n_intervals==1)
643  return (std::vector<IteratorPair>
644  (1, IteratorPair(begin, end)));
645 
646  // if more than one interval requested, do the full work
647  const unsigned int n_elements = std::distance (begin, end);
648  const unsigned int n_elements_per_interval = n_elements / n_intervals;
649  const unsigned int residual = n_elements % n_intervals;
650 
651  std::vector<IteratorPair> return_values (n_intervals);
652 
653  return_values[0].first = begin;
654  for (unsigned int i=0; i<n_intervals; ++i)
655  {
656  if (i != n_intervals-1)
657  {
658  return_values[i].second = return_values[i].first;
659  // note: the cast is performed to avoid a warning of gcc
660  // that in the library `dist>=0' is checked (dist has a
661  // template type, which here is unsigned if no cast is
662  // performed)
663  std::advance (return_values[i].second,
664  static_cast<signed int>(n_elements_per_interval));
665  // distribute residual in division equally among the first
666  // few subintervals
667  if (i < residual)
668  ++return_values[i].second;
669 
670  return_values[i+1].first = return_values[i].second;
671  }
672  else
673  return_values[i].second = end;
674  }
675  return return_values;
676  }
677 }
678 
679 #endif // DOXYGEN
680 
681 namespace Threads
682 {
683  namespace internal
684  {
692  template <typename RT> struct return_value
693  {
694  private:
695  RT value;
696  public:
697  inline return_value () : value() {}
698 
699  inline RT get () const
700  {
701  return value;
702  }
703 
704  inline void set (RT v)
705  {
706  value = v;
707  }
708  };
709 
710 
720  template <typename RT> struct return_value<RT &>
721  {
722  private:
723  RT *value;
724  public:
725  inline return_value () : value(0) {}
726 
727  inline RT &get () const
728  {
729  return *value;
730  }
731  inline void set (RT &v)
732  {
733  value = &v;
734  }
735  };
736 
737 
746  template <> struct return_value<void>
747  {
748  static inline void get () {}
749  };
750  }
751 
752 
753 
754  namespace internal
755  {
756  template <typename RT>
757  inline void call (const std_cxx11::function<RT ()> &function,
758  internal::return_value<RT> &ret_val)
759  {
760  ret_val.set (function());
761  }
762 
763 
764  inline void call (const std_cxx11::function<void ()> &function,
765  internal::return_value<void> &)
766  {
767  function();
768  }
769  }
770 
771 
772 
773  namespace internal
774  {
784  template <typename RT, typename ArgList,
785  int length = std_cxx11::tuple_size<ArgList>::value>
786  struct fun_ptr_helper;
787 
788 
795  template <typename RT, typename ArgList>
796  struct fun_ptr_helper<RT, ArgList, 0>
797  {
798  typedef RT (type) ();
799  };
800 
801 
808  template <typename RT, typename ArgList>
809  struct fun_ptr_helper<RT, ArgList, 1>
810  {
811  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type);
812  };
813 
814 
821  template <typename RT, typename ArgList>
822  struct fun_ptr_helper<RT, ArgList, 2>
823  {
824  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
825  typename std_cxx11::tuple_element<1,ArgList>::type);
826  };
827 
828 
835  template <typename RT, typename ArgList>
836  struct fun_ptr_helper<RT, ArgList, 3>
837  {
838  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
839  typename std_cxx11::tuple_element<1,ArgList>::type,
840  typename std_cxx11::tuple_element<2,ArgList>::type);
841  };
842 
843 
850  template <typename RT, typename ArgList>
851  struct fun_ptr_helper<RT, ArgList, 4>
852  {
853  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
854  typename std_cxx11::tuple_element<1,ArgList>::type,
855  typename std_cxx11::tuple_element<2,ArgList>::type,
856  typename std_cxx11::tuple_element<3,ArgList>::type);
857  };
858 
859 
866  template <typename RT, typename ArgList>
867  struct fun_ptr_helper<RT, ArgList, 5>
868  {
869  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
870  typename std_cxx11::tuple_element<1,ArgList>::type,
871  typename std_cxx11::tuple_element<2,ArgList>::type,
872  typename std_cxx11::tuple_element<3,ArgList>::type,
873  typename std_cxx11::tuple_element<4,ArgList>::type);
874  };
875 
876 
883  template <typename RT, typename ArgList>
884  struct fun_ptr_helper<RT, ArgList, 6>
885  {
886  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
887  typename std_cxx11::tuple_element<1,ArgList>::type,
888  typename std_cxx11::tuple_element<2,ArgList>::type,
889  typename std_cxx11::tuple_element<3,ArgList>::type,
890  typename std_cxx11::tuple_element<4,ArgList>::type,
891  typename std_cxx11::tuple_element<5,ArgList>::type);
892  };
893 
894 
901  template <typename RT, typename ArgList>
902  struct fun_ptr_helper<RT, ArgList, 7>
903  {
904  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
905  typename std_cxx11::tuple_element<1,ArgList>::type,
906  typename std_cxx11::tuple_element<2,ArgList>::type,
907  typename std_cxx11::tuple_element<3,ArgList>::type,
908  typename std_cxx11::tuple_element<4,ArgList>::type,
909  typename std_cxx11::tuple_element<5,ArgList>::type,
910  typename std_cxx11::tuple_element<6,ArgList>::type);
911  };
912 
913 
920  template <typename RT, typename ArgList>
921  struct fun_ptr_helper<RT, ArgList, 8>
922  {
923  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
924  typename std_cxx11::tuple_element<1,ArgList>::type,
925  typename std_cxx11::tuple_element<2,ArgList>::type,
926  typename std_cxx11::tuple_element<3,ArgList>::type,
927  typename std_cxx11::tuple_element<4,ArgList>::type,
928  typename std_cxx11::tuple_element<5,ArgList>::type,
929  typename std_cxx11::tuple_element<6,ArgList>::type,
930  typename std_cxx11::tuple_element<7,ArgList>::type);
931  };
932 
933 
940  template <typename RT, typename ArgList>
941  struct fun_ptr_helper<RT, ArgList, 9>
942  {
943  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
944  typename std_cxx11::tuple_element<1,ArgList>::type,
945  typename std_cxx11::tuple_element<2,ArgList>::type,
946  typename std_cxx11::tuple_element<3,ArgList>::type,
947  typename std_cxx11::tuple_element<4,ArgList>::type,
948  typename std_cxx11::tuple_element<5,ArgList>::type,
949  typename std_cxx11::tuple_element<6,ArgList>::type,
950  typename std_cxx11::tuple_element<7,ArgList>::type,
951  typename std_cxx11::tuple_element<8,ArgList>::type);
952  };
953 
954 
955 
962  template <typename RT, typename ArgList>
963  struct fun_ptr_helper<RT, ArgList, 10>
964  {
965  typedef RT (type) (typename std_cxx11::tuple_element<0,ArgList>::type,
966  typename std_cxx11::tuple_element<1,ArgList>::type,
967  typename std_cxx11::tuple_element<2,ArgList>::type,
968  typename std_cxx11::tuple_element<3,ArgList>::type,
969  typename std_cxx11::tuple_element<4,ArgList>::type,
970  typename std_cxx11::tuple_element<5,ArgList>::type,
971  typename std_cxx11::tuple_element<6,ArgList>::type,
972  typename std_cxx11::tuple_element<7,ArgList>::type,
973  typename std_cxx11::tuple_element<8,ArgList>::type,
974  typename std_cxx11::tuple_element<9,ArgList>::type);
975  };
976 
977 
978 
989  template <typename RT, typename ArgList>
990  struct fun_ptr
991  {
992  typedef typename fun_ptr_helper<RT,ArgList>::type type;
993  };
994  }
995 
996 
997 
998  namespace internal
999  {
1000 #ifdef DEAL_II_WITH_THREADS
1001 
1012  template <typename RT>
1014  {
1018  std_cxx11::thread thread;
1019 
1028  std_cxx11::shared_ptr<return_value<RT> > ret_val;
1029 
1062 
1067 
1072  :
1073  thread_is_active (false)
1074  {}
1075 
1076  ~ThreadDescriptor ()
1077  {
1078  if (!thread_is_active)
1079  return;
1080  thread.detach();
1081  thread_is_active = false;
1082  }
1083 
1088  void start (const std_cxx11::function<RT ()> &function)
1089  {
1090  thread_is_active = true;
1091  ret_val.reset(new return_value<RT>());
1092  thread = std_cxx11::thread (thread_entry_point, function, ret_val);
1093  }
1094 
1095 
1099  void join ()
1100  {
1101  // see if the thread hasn't been joined yet. if it has, then
1102  // join() is a no-op. use schmidt's double-checking strategy
1103  // to use the mutex only when necessary
1104  if (thread_is_active == false)
1105  return;
1106 
1108  if (thread_is_active == true)
1109  {
1110  Assert (thread.joinable(), ExcInternalError());
1111  thread.join ();
1112  thread_is_active = false;
1113  }
1114  }
1115 
1116  private:
1117 
1121  static
1122  void thread_entry_point (const std_cxx11::function<RT ()> function,
1123  std_cxx11::shared_ptr<return_value<RT> > ret_val)
1124  {
1125  // call the function in question. since an exception that is
1126  // thrown from one of the called functions will not propagate
1127  // to the main thread, it will kill the program if not treated
1128  // here before we return to the operating system's thread
1129  // library
1130  internal::register_thread ();
1131  try
1132  {
1133  call (function, *ret_val);
1134  }
1135  catch (const std::exception &exc)
1136  {
1137  internal::handle_std_exception (exc);
1138  }
1139  catch (...)
1140  {
1141  internal::handle_unknown_exception ();
1142  }
1143  internal::deregister_thread ();
1144  }
1145  };
1146 
1147 #else
1148 
1156  template <typename RT>
1157  struct ThreadDescriptor
1158  {
1163  std_cxx11::shared_ptr<return_value<RT> > ret_val;
1164 
1169  void start (const std_cxx11::function<RT ()> &function)
1170  {
1171  ret_val.reset(new return_value<RT>());
1172  call (function, *ret_val);
1173  }
1174 
1178  void join ()
1179  {}
1180  };
1181 
1182 #endif
1183  }
1184 
1185 
1208  template <typename RT = void>
1209  class Thread
1210  {
1211  public:
1215  Thread (const std_cxx11::function<RT ()> &function)
1216  :
1217  thread_descriptor (new internal::ThreadDescriptor<RT>())
1218  {
1219  // in a second step, start the thread.
1220  thread_descriptor->start (function);
1221  }
1222 
1228  Thread () {}
1229 
1233  Thread (const Thread<RT> &t)
1234  :
1236  {}
1237 
1243  void join () const
1244  {
1245  if (thread_descriptor)
1246  thread_descriptor->join ();
1247  }
1248 
1254  {
1255  join ();
1256  return thread_descriptor->ret_val->get();
1257  }
1258 
1263  bool valid () const
1264  {
1265  return static_cast<bool>(thread_descriptor);
1266  }
1267 
1268 
1274  bool operator == (const Thread &t) const
1275  {
1277  }
1278 
1279  private:
1286  std_cxx11::shared_ptr<internal::ThreadDescriptor<RT> > thread_descriptor;
1287  };
1288 
1289 
1290  namespace internal
1291  {
1299  template <typename T>
1301  {
1302  static T act (T &t)
1303  {
1304  return t;
1305  }
1306  };
1307 
1308 
1309 
1317  template <typename T>
1318  struct maybe_make_ref<T &>
1319  {
1320  static std_cxx11::reference_wrapper<T> act (T &t)
1321  {
1322  return std_cxx11::ref(t);
1323  }
1324  };
1325  }
1326 
1327 
1328 
1329  namespace internal
1330  {
1344  template <typename RT, typename ArgList, int length>
1345  class fun_encapsulator;
1346 
1347 
1348 // ----------- encapsulators for function objects
1349 
1355  template <typename RT, typename ArgList>
1356  class fun_encapsulator<RT, ArgList, 0>
1357  {
1358  public:
1359  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1360  : function (*function)
1361  {}
1362 
1363  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1364  : function (function)
1365  {}
1366 
1367  inline
1368  Thread<RT>
1369  operator() ()
1370  {
1371  return Thread<RT> (function);
1372  }
1373 
1374  private:
1375  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1376  };
1377 
1383  template <typename RT, typename ArgList>
1384  class fun_encapsulator<RT, ArgList, 1>
1385  {
1386  public:
1387  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1388  : function (*function)
1389  {}
1390 
1391  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1392  : function (function)
1393  {}
1394 
1395  inline
1396  Thread<RT>
1397  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1)
1398  {
1399  return
1400  Thread<RT>
1401  (std_cxx11::bind (function,
1402  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1)));
1403  }
1404 
1405  private:
1406  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1407  };
1408 
1414  template <typename RT, typename ArgList>
1415  class fun_encapsulator<RT, ArgList, 2>
1416  {
1417  public:
1418  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1419  : function (*function)
1420  {}
1421 
1422  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1423  : function (function)
1424  {}
1425 
1426  inline
1427  Thread<RT>
1428  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1429  typename std_cxx11::tuple_element<1,ArgList>::type arg2)
1430  {
1431  return
1432  Thread<RT>
1433  (std_cxx11::bind (function,
1434  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1435  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2)));
1436  }
1437 
1438  private:
1439  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1440  };
1441 
1447  template <typename RT, typename ArgList>
1448  class fun_encapsulator<RT, ArgList, 3>
1449  {
1450  public:
1451  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1452  : function (*function)
1453  {}
1454 
1455  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1456  : function (function)
1457  {}
1458 
1459  inline
1460  Thread<RT>
1461  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1462  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1463  typename std_cxx11::tuple_element<2,ArgList>::type arg3)
1464  {
1465  return
1466  Thread<RT>
1467  (std_cxx11::bind (function,
1468  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1469  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1470  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3)));
1471  }
1472 
1473  private:
1474  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1475  };
1476 
1482  template <typename RT, typename ArgList>
1483  class fun_encapsulator<RT, ArgList, 4>
1484  {
1485  public:
1486  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1487  : function (*function)
1488  {}
1489 
1490  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1491  : function (function)
1492  {}
1493 
1494  inline
1495  Thread<RT>
1496  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1497  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1498  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1499  typename std_cxx11::tuple_element<3,ArgList>::type arg4)
1500  {
1501  return
1502  Thread<RT>
1503  (std_cxx11::bind (function,
1504  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1505  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1506  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1507  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4)));
1508  }
1509 
1510  private:
1511  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1512  };
1513 
1519  template <typename RT, typename ArgList>
1520  class fun_encapsulator<RT, ArgList, 5>
1521  {
1522  public:
1523  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1524  : function (*function)
1525  {}
1526 
1527  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1528  : function (function)
1529  {}
1530 
1531  inline
1532  Thread<RT>
1533  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1534  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1535  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1536  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1537  typename std_cxx11::tuple_element<4,ArgList>::type arg5)
1538  {
1539  return
1540  Thread<RT>
1541  (std_cxx11::bind (function,
1542  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1543  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1544  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1545  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1546  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5)));
1547  }
1548 
1549  private:
1550  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1551  };
1552 
1558  template <typename RT, typename ArgList>
1559  class fun_encapsulator<RT, ArgList, 6>
1560  {
1561  public:
1562  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1563  : function (*function)
1564  {}
1565 
1566  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1567  : function (function)
1568  {}
1569 
1570  inline
1571  Thread<RT>
1572  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1573  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1574  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1575  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1576  typename std_cxx11::tuple_element<4,ArgList>::type arg5,
1577  typename std_cxx11::tuple_element<5,ArgList>::type arg6)
1578  {
1579  return
1580  Thread<RT>
1581  (std_cxx11::bind (function,
1582  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1583  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1584  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1585  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1586  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5),
1587  internal::maybe_make_ref<typename std_cxx11::tuple_element<5,ArgList>::type>::act(arg6)));
1588  }
1589 
1590  private:
1591  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1592  };
1593 
1599  template <typename RT, typename ArgList>
1600  class fun_encapsulator<RT, ArgList, 7>
1601  {
1602  public:
1603  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1604  : function (*function)
1605  {}
1606 
1607  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1608  : function (function)
1609  {}
1610 
1611  inline
1612  Thread<RT>
1613  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1614  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1615  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1616  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1617  typename std_cxx11::tuple_element<4,ArgList>::type arg5,
1618  typename std_cxx11::tuple_element<5,ArgList>::type arg6,
1619  typename std_cxx11::tuple_element<6,ArgList>::type arg7)
1620  {
1621  return
1622  Thread<RT>
1623  (std_cxx11::bind (function,
1624  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1625  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1626  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1627  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1628  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5),
1629  internal::maybe_make_ref<typename std_cxx11::tuple_element<5,ArgList>::type>::act(arg6),
1630  internal::maybe_make_ref<typename std_cxx11::tuple_element<6,ArgList>::type>::act(arg7)));
1631  }
1632 
1633  private:
1634  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1635  };
1636 
1642  template <typename RT, typename ArgList>
1643  class fun_encapsulator<RT, ArgList, 8>
1644  {
1645  public:
1646  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1647  : function (*function)
1648  {}
1649 
1650  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1651  : function (function)
1652  {}
1653 
1654  inline
1655  Thread<RT>
1656  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1657  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1658  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1659  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1660  typename std_cxx11::tuple_element<4,ArgList>::type arg5,
1661  typename std_cxx11::tuple_element<5,ArgList>::type arg6,
1662  typename std_cxx11::tuple_element<6,ArgList>::type arg7,
1663  typename std_cxx11::tuple_element<7,ArgList>::type arg8)
1664  {
1665  return
1666  Thread<RT>
1667  (std_cxx11::bind (function,
1668  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1669  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1670  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1671  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1672  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5),
1673  internal::maybe_make_ref<typename std_cxx11::tuple_element<5,ArgList>::type>::act(arg6),
1674  internal::maybe_make_ref<typename std_cxx11::tuple_element<6,ArgList>::type>::act(arg7),
1675  internal::maybe_make_ref<typename std_cxx11::tuple_element<7,ArgList>::type>::act(arg8)));
1676  }
1677 
1678  private:
1679  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1680  };
1681 
1687  template <typename RT, typename ArgList>
1688  class fun_encapsulator<RT, ArgList, 9>
1689  {
1690  public:
1691  fun_encapsulator (typename internal::fun_ptr<RT,ArgList>::type *function)
1692  : function (*function)
1693  {}
1694 
1695  fun_encapsulator (const std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> &function)
1696  : function (function)
1697  {}
1698 
1699  inline
1700  Thread<RT>
1701  operator() (typename std_cxx11::tuple_element<0,ArgList>::type arg1,
1702  typename std_cxx11::tuple_element<1,ArgList>::type arg2,
1703  typename std_cxx11::tuple_element<2,ArgList>::type arg3,
1704  typename std_cxx11::tuple_element<3,ArgList>::type arg4,
1705  typename std_cxx11::tuple_element<4,ArgList>::type arg5,
1706  typename std_cxx11::tuple_element<5,ArgList>::type arg6,
1707  typename std_cxx11::tuple_element<6,ArgList>::type arg7,
1708  typename std_cxx11::tuple_element<7,ArgList>::type arg8,
1709  typename std_cxx11::tuple_element<8,ArgList>::type arg9)
1710  {
1711  return
1712  Thread<RT>
1713  (std_cxx11::bind (function,
1714  internal::maybe_make_ref<typename std_cxx11::tuple_element<0,ArgList>::type>::act(arg1),
1715  internal::maybe_make_ref<typename std_cxx11::tuple_element<1,ArgList>::type>::act(arg2),
1716  internal::maybe_make_ref<typename std_cxx11::tuple_element<2,ArgList>::type>::act(arg3),
1717  internal::maybe_make_ref<typename std_cxx11::tuple_element<3,ArgList>::type>::act(arg4),
1718  internal::maybe_make_ref<typename std_cxx11::tuple_element<4,ArgList>::type>::act(arg5),
1719  internal::maybe_make_ref<typename std_cxx11::tuple_element<5,ArgList>::type>::act(arg6),
1720  internal::maybe_make_ref<typename std_cxx11::tuple_element<6,ArgList>::type>::act(arg7),
1721  internal::maybe_make_ref<typename std_cxx11::tuple_element<7,ArgList>::type>::act(arg8),
1722  internal::maybe_make_ref<typename std_cxx11::tuple_element<8,ArgList>::type>::act(arg9)));
1723  }
1724 
1725  private:
1726  std_cxx11::function<typename internal::fun_ptr<RT,ArgList>::type> function;
1727  };
1728  }
1729 
1730 
1731 
1732 // ----------- thread starters for functions not taking any parameters
1733 
1742  template <typename RT>
1743  inline
1744  Thread<RT>
1745  new_thread (const std_cxx11::function<RT ()> &function)
1746  {
1747  return Thread<RT>(function);
1748  }
1749 
1750 
1751 #ifdef DEAL_II_WITH_CXX11
1752 
1816  template <typename FunctionObjectType>
1817  inline
1818  auto
1819  new_thread (FunctionObjectType function_object)
1821  {
1822  typedef decltype(function_object()) return_type;
1823  return Thread<return_type>(std_cxx11::function<return_type ()>(function_object));
1824  }
1825 
1826 #endif
1827 
1828 
1835  template <typename RT>
1836  inline
1837  Thread<RT>
1838  new_thread (RT (*fun_ptr)())
1839  {
1840  return new_thread (std_cxx11::function<RT ()> (fun_ptr));
1841  }
1842 
1843 
1850  template <typename RT, typename C>
1851  inline
1852  Thread<RT>
1853  new_thread (RT (C::*fun_ptr)(),
1854  typename identity<C>::type &c)
1855  {
1856  return
1857  new_thread (std_cxx11::function<RT ()>
1858  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c))));
1859  }
1860 
1861 
1862 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
1863 
1869  template <typename RT, typename C>
1870  inline
1871  Thread<RT>
1872  new_thread (RT (C::*fun_ptr)() const,
1873  const typename identity<C>::type &c)
1874  {
1875  return
1876  new_thread (std_cxx11::function<RT ()>
1877  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c))));
1878  }
1879 #endif
1880 
1881 
1882 
1883 // ----------- thread starters for unary functions
1884 
1891  template <typename RT, typename Arg1>
1892  inline
1893  Thread<RT>
1894  new_thread (RT (*fun_ptr)(Arg1),
1895  typename identity<Arg1>::type arg1)
1896  {
1897  return
1898  new_thread (std_cxx11::function<RT ()>
1899  (std_cxx11::bind(fun_ptr,
1901  }
1902 
1903 
1904 
1911  template <typename RT, typename C, typename Arg1>
1912  inline
1913  Thread<RT>
1914  new_thread (RT (C::*fun_ptr)(Arg1),
1915  typename identity<C>::type &c,
1916  typename identity<Arg1>::type arg1)
1917  {
1918  return
1919  new_thread (std_cxx11::function<RT ()>
1920  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
1922  }
1923 
1924 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
1925 
1931  template <typename RT, typename C, typename Arg1>
1932  inline
1933  Thread<RT>
1934  new_thread (RT (C::*fun_ptr)(Arg1) const,
1935  typename identity<const C>::type &c,
1936  typename identity<Arg1>::type arg1)
1937  {
1938  return
1939  new_thread (std_cxx11::function<RT ()>
1940  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
1942  }
1943 #endif
1944 
1945 // ----------- thread starters for binary functions
1946 
1953  template <typename RT, typename Arg1, typename Arg2>
1954  inline
1955  Thread<RT>
1956  new_thread (RT (*fun_ptr)(Arg1,Arg2),
1957  typename identity<Arg1>::type arg1,
1958  typename identity<Arg2>::type arg2)
1959  {
1960  return
1961  new_thread (std_cxx11::function<RT ()>
1962  (std_cxx11::bind(fun_ptr,
1965  }
1966 
1967 
1968 
1975  template <typename RT, typename C, typename Arg1, typename Arg2>
1976  inline
1977  Thread<RT>
1978  new_thread (RT (C::*fun_ptr)(Arg1,Arg2),
1979  typename identity<C>::type &c,
1980  typename identity<Arg1>::type arg1,
1981  typename identity<Arg2>::type arg2)
1982  {
1983  return
1984  new_thread (std_cxx11::function<RT ()>
1985  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
1988  }
1989 
1990 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
1991 
1997  template <typename RT, typename C, typename Arg1, typename Arg2>
1998  inline
1999  Thread<RT>
2000  new_thread (RT (C::*fun_ptr)(Arg1,Arg2) const,
2001  typename identity<const C>::type &c,
2002  typename identity<Arg1>::type arg1,
2003  typename identity<Arg2>::type arg2)
2004  {
2005  return
2006  new_thread (std_cxx11::function<RT ()>
2007  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2010  }
2011 #endif
2012 
2013 // ----------- thread starters for ternary functions
2014 
2021  template <typename RT,
2022  typename Arg1, typename Arg2, typename Arg3>
2023  inline
2024  Thread<RT>
2025  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3),
2026  typename identity<Arg1>::type arg1,
2027  typename identity<Arg2>::type arg2,
2028  typename identity<Arg3>::type arg3)
2029  {
2030  return
2031  new_thread (std_cxx11::function<RT ()>
2032  (std_cxx11::bind(fun_ptr,
2036  }
2037 
2038 
2039 
2046  template <typename RT, typename C,
2047  typename Arg1, typename Arg2, typename Arg3>
2048  inline
2049  Thread<RT>
2050  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3),
2051  typename identity<C>::type &c,
2052  typename identity<Arg1>::type arg1,
2053  typename identity<Arg2>::type arg2,
2054  typename identity<Arg3>::type arg3)
2055  {
2056  return
2057  new_thread (std_cxx11::function<RT ()>
2058  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2062  }
2063 
2064 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2065 
2071  template <typename RT, typename C,
2072  typename Arg1, typename Arg2, typename Arg3>
2073  inline
2074  Thread<RT>
2075  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const,
2076  typename identity<const C>::type &c,
2077  typename identity<Arg1>::type arg1,
2078  typename identity<Arg2>::type arg2,
2079  typename identity<Arg3>::type arg3)
2080  {
2081  return
2082  new_thread (std_cxx11::function<RT ()>
2083  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2087  }
2088 #endif
2089 
2090 
2091 // ----------- thread starters for functions with 4 arguments
2092 
2099  template <typename RT,
2100  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2101  inline
2102  Thread<RT>
2103  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
2104  typename identity<Arg1>::type arg1,
2105  typename identity<Arg2>::type arg2,
2106  typename identity<Arg3>::type arg3,
2107  typename identity<Arg4>::type arg4)
2108  {
2109  return
2110  new_thread (std_cxx11::function<RT ()>
2111  (std_cxx11::bind(fun_ptr,
2116  }
2117 
2118 
2119 
2126  template <typename RT, typename C,
2127  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2128  inline
2129  Thread<RT>
2130  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
2131  typename identity<C>::type &c,
2132  typename identity<Arg1>::type arg1,
2133  typename identity<Arg2>::type arg2,
2134  typename identity<Arg3>::type arg3,
2135  typename identity<Arg4>::type arg4)
2136  {
2137  return
2138  new_thread (std_cxx11::function<RT ()>
2139  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2144  }
2145 
2146 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2147 
2153  template <typename RT, typename C,
2154  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
2155  inline
2156  Thread<RT>
2157  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) 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  {
2164  return
2165  new_thread (std_cxx11::function<RT ()>
2166  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2171  }
2172 #endif
2173 
2174 // ----------- thread starters for functions with 5 arguments
2175 
2182  template <typename RT,
2183  typename Arg1, typename Arg2, typename Arg3,
2184  typename Arg4, typename Arg5>
2185  inline
2186  Thread<RT>
2187  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
2188  typename identity<Arg1>::type arg1,
2189  typename identity<Arg2>::type arg2,
2190  typename identity<Arg3>::type arg3,
2191  typename identity<Arg4>::type arg4,
2192  typename identity<Arg5>::type arg5)
2193  {
2194  return
2195  new_thread (std_cxx11::function<RT ()>
2196  (std_cxx11::bind(fun_ptr,
2202  }
2203 
2204 
2205 
2212  template <typename RT, typename C,
2213  typename Arg1, typename Arg2, typename Arg3,
2214  typename Arg4, typename Arg5>
2215  inline
2216  Thread<RT>
2217  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
2218  typename identity<C>::type &c,
2219  typename identity<Arg1>::type arg1,
2220  typename identity<Arg2>::type arg2,
2221  typename identity<Arg3>::type arg3,
2222  typename identity<Arg4>::type arg4,
2223  typename identity<Arg5>::type arg5)
2224  {
2225  return
2226  new_thread (std_cxx11::function<RT ()>
2227  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2233  }
2234 
2235 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2236 
2242  template <typename RT, typename C,
2243  typename Arg1, typename Arg2, typename Arg3,
2244  typename Arg4, typename Arg5>
2245  inline
2246  Thread<RT>
2247  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const,
2248  typename identity<const C>::type &c,
2249  typename identity<Arg1>::type arg1,
2250  typename identity<Arg2>::type arg2,
2251  typename identity<Arg3>::type arg3,
2252  typename identity<Arg4>::type arg4,
2253  typename identity<Arg5>::type arg5)
2254  {
2255  return
2256  new_thread (std_cxx11::function<RT ()>
2257  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2263  }
2264 #endif
2265 
2266 // ----------- thread starters for functions with 6 arguments
2267 
2274  template <typename RT,
2275  typename Arg1, typename Arg2, typename Arg3,
2276  typename Arg4, typename Arg5, typename Arg6>
2277  inline
2278  Thread<RT>
2279  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
2280  typename identity<Arg1>::type arg1,
2281  typename identity<Arg2>::type arg2,
2282  typename identity<Arg3>::type arg3,
2283  typename identity<Arg4>::type arg4,
2284  typename identity<Arg5>::type arg5,
2285  typename identity<Arg6>::type arg6)
2286  {
2287  return
2288  new_thread (std_cxx11::function<RT ()>
2289  (std_cxx11::bind(fun_ptr,
2296  }
2297 
2298 
2299 
2306  template <typename RT, typename C,
2307  typename Arg1, typename Arg2, typename Arg3,
2308  typename Arg4, typename Arg5, typename Arg6>
2309  inline
2310  Thread<RT>
2311  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
2312  typename identity<C>::type &c,
2313  typename identity<Arg1>::type arg1,
2314  typename identity<Arg2>::type arg2,
2315  typename identity<Arg3>::type arg3,
2316  typename identity<Arg4>::type arg4,
2317  typename identity<Arg5>::type arg5,
2318  typename identity<Arg6>::type arg6)
2319  {
2320  return
2321  new_thread (std_cxx11::function<RT ()>
2322  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2329  }
2330 
2331 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2332 
2338  template <typename RT, typename C,
2339  typename Arg1, typename Arg2, typename Arg3,
2340  typename Arg4, typename Arg5, typename Arg6>
2341  inline
2342  Thread<RT>
2343  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const,
2344  typename identity<const C>::type &c,
2345  typename identity<Arg1>::type arg1,
2346  typename identity<Arg2>::type arg2,
2347  typename identity<Arg3>::type arg3,
2348  typename identity<Arg4>::type arg4,
2349  typename identity<Arg5>::type arg5,
2350  typename identity<Arg6>::type arg6)
2351  {
2352  return
2353  new_thread (std_cxx11::function<RT ()>
2354  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2361  }
2362 #endif
2363 
2364 // ----------- thread starters for functions with 7 arguments
2365 
2372  template <typename RT,
2373  typename Arg1, typename Arg2, typename Arg3,
2374  typename Arg4, typename Arg5, typename Arg6,
2375  typename Arg7>
2376  inline
2377  Thread<RT>
2378  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
2379  typename identity<Arg1>::type arg1,
2380  typename identity<Arg2>::type arg2,
2381  typename identity<Arg3>::type arg3,
2382  typename identity<Arg4>::type arg4,
2383  typename identity<Arg5>::type arg5,
2384  typename identity<Arg6>::type arg6,
2385  typename identity<Arg7>::type arg7)
2386  {
2387  return
2388  new_thread (std_cxx11::function<RT ()>
2389  (std_cxx11::bind(fun_ptr,
2397  }
2398 
2399 
2400 
2407  template <typename RT, typename C,
2408  typename Arg1, typename Arg2, typename Arg3,
2409  typename Arg4, typename Arg5, typename Arg6,
2410  typename Arg7>
2411  inline
2412  Thread<RT>
2413  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
2414  typename identity<C>::type &c,
2415  typename identity<Arg1>::type arg1,
2416  typename identity<Arg2>::type arg2,
2417  typename identity<Arg3>::type arg3,
2418  typename identity<Arg4>::type arg4,
2419  typename identity<Arg5>::type arg5,
2420  typename identity<Arg6>::type arg6,
2421  typename identity<Arg7>::type arg7)
2422  {
2423  return
2424  new_thread (std_cxx11::function<RT ()>
2425  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2433  }
2434 
2435 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2436 
2442  template <typename RT, typename C,
2443  typename Arg1, typename Arg2, typename Arg3,
2444  typename Arg4, typename Arg5, typename Arg6,
2445  typename Arg7>
2446  inline
2447  Thread<RT>
2448  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const,
2449  typename identity<const C>::type &c,
2450  typename identity<Arg1>::type arg1,
2451  typename identity<Arg2>::type arg2,
2452  typename identity<Arg3>::type arg3,
2453  typename identity<Arg4>::type arg4,
2454  typename identity<Arg5>::type arg5,
2455  typename identity<Arg6>::type arg6,
2456  typename identity<Arg7>::type arg7)
2457  {
2458  return
2459  new_thread (std_cxx11::function<RT ()>
2460  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2468  }
2469 #endif
2470 
2471 // ----------- thread starters for functions with 8 arguments
2472 
2479  template <typename RT,
2480  typename Arg1, typename Arg2, typename Arg3,
2481  typename Arg4, typename Arg5, typename Arg6,
2482  typename Arg7, typename Arg8>
2483  inline
2484  Thread<RT>
2485  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2486  Arg6,Arg7,Arg8),
2487  typename identity<Arg1>::type arg1,
2488  typename identity<Arg2>::type arg2,
2489  typename identity<Arg3>::type arg3,
2490  typename identity<Arg4>::type arg4,
2491  typename identity<Arg5>::type arg5,
2492  typename identity<Arg6>::type arg6,
2493  typename identity<Arg7>::type arg7,
2494  typename identity<Arg8>::type arg8)
2495  {
2496  return
2497  new_thread (std_cxx11::function<RT ()>
2498  (std_cxx11::bind(fun_ptr,
2507  }
2508 
2509 
2510 
2517  template <typename RT, typename C,
2518  typename Arg1, typename Arg2, typename Arg3,
2519  typename Arg4, typename Arg5, typename Arg6,
2520  typename Arg7, typename Arg8>
2521  inline
2522  Thread<RT>
2523  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2524  Arg6,Arg7,Arg8),
2525  typename identity<C>::type &c,
2526  typename identity<Arg1>::type arg1,
2527  typename identity<Arg2>::type arg2,
2528  typename identity<Arg3>::type arg3,
2529  typename identity<Arg4>::type arg4,
2530  typename identity<Arg5>::type arg5,
2531  typename identity<Arg6>::type arg6,
2532  typename identity<Arg7>::type arg7,
2533  typename identity<Arg8>::type arg8)
2534  {
2535  return
2536  new_thread (std_cxx11::function<RT ()>
2537  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2546  }
2547 
2548 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2549 
2555  template <typename RT, typename C,
2556  typename Arg1, typename Arg2, typename Arg3,
2557  typename Arg4, typename Arg5, typename Arg6,
2558  typename Arg7, typename Arg8>
2559  inline
2560  Thread<RT>
2561  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2562  Arg6,Arg7,Arg8) const,
2563  typename identity<const C>::type &c,
2564  typename identity<Arg1>::type arg1,
2565  typename identity<Arg2>::type arg2,
2566  typename identity<Arg3>::type arg3,
2567  typename identity<Arg4>::type arg4,
2568  typename identity<Arg5>::type arg5,
2569  typename identity<Arg6>::type arg6,
2570  typename identity<Arg7>::type arg7,
2571  typename identity<Arg8>::type arg8)
2572  {
2573  return
2574  new_thread (std_cxx11::function<RT ()>
2575  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2584  }
2585 #endif
2586 
2587 // ----------- thread starters for functions with 9 arguments
2588 
2595  template <typename RT,
2596  typename Arg1, typename Arg2, typename Arg3,
2597  typename Arg4, typename Arg5, typename Arg6,
2598  typename Arg7, typename Arg8, typename Arg9>
2599  inline
2600  Thread<RT>
2601  new_thread (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2602  Arg6,Arg7,Arg8,Arg9),
2603  typename identity<Arg1>::type arg1,
2604  typename identity<Arg2>::type arg2,
2605  typename identity<Arg3>::type arg3,
2606  typename identity<Arg4>::type arg4,
2607  typename identity<Arg5>::type arg5,
2608  typename identity<Arg6>::type arg6,
2609  typename identity<Arg7>::type arg7,
2610  typename identity<Arg8>::type arg8,
2611  typename identity<Arg9>::type arg9)
2612  {
2613  return
2614  new_thread (std_cxx11::function<RT ()>
2615  (std_cxx11::bind(fun_ptr,
2625  }
2626 
2627 
2628 
2635  template <typename RT, typename C,
2636  typename Arg1, typename Arg2, typename Arg3,
2637  typename Arg4, typename Arg5, typename Arg6,
2638  typename Arg7, typename Arg8, typename Arg9>
2639  inline
2640  Thread<RT>
2641  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2642  Arg6,Arg7,Arg8,Arg9),
2643  typename identity<C>::type &c,
2644  typename identity<Arg1>::type arg1,
2645  typename identity<Arg2>::type arg2,
2646  typename identity<Arg3>::type arg3,
2647  typename identity<Arg4>::type arg4,
2648  typename identity<Arg5>::type arg5,
2649  typename identity<Arg6>::type arg6,
2650  typename identity<Arg7>::type arg7,
2651  typename identity<Arg8>::type arg8,
2652  typename identity<Arg9>::type arg9)
2653  {
2654  return
2655  new_thread (std_cxx11::function<RT ()>
2656  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
2666  }
2667 
2668 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
2669 
2675  template <typename RT, typename C,
2676  typename Arg1, typename Arg2, typename Arg3,
2677  typename Arg4, typename Arg5, typename Arg6,
2678  typename Arg7, typename Arg8, typename Arg9>
2679  inline
2680  Thread<RT>
2681  new_thread (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
2682  Arg6,Arg7,Arg8,Arg9) const,
2683  typename identity<const C>::type &c,
2684  typename identity<Arg1>::type arg1,
2685  typename identity<Arg2>::type arg2,
2686  typename identity<Arg3>::type arg3,
2687  typename identity<Arg4>::type arg4,
2688  typename identity<Arg5>::type arg5,
2689  typename identity<Arg6>::type arg6,
2690  typename identity<Arg7>::type arg7,
2691  typename identity<Arg8>::type arg8,
2692  typename identity<Arg9>::type arg9)
2693  {
2694  return
2695  new_thread (std_cxx11::function<RT ()>
2696  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
2706  }
2707 #endif
2708 
2709 // ------------------------ ThreadGroup -------------------------------------
2710 
2719  template <typename RT = void>
2721  {
2722  public:
2727  {
2728  threads.push_back (t);
2729  return *this;
2730  }
2731 
2738  void join_all () const
2739  {
2740  for (typename std::list<Thread<RT> >::const_iterator
2741  t=threads.begin(); t!=threads.end(); ++t)
2742  t->join ();
2743  }
2744 
2745  private:
2749  std::list<Thread<RT> > threads;
2750  };
2751 
2752 
2753  template <typename> class Task;
2754 
2755 
2756  namespace internal
2757  {
2758 #ifdef DEAL_II_WITH_THREADS
2759 
2760  template <typename> struct TaskDescriptor;
2761 
2765  template <typename RT>
2766  struct TaskEntryPoint : public tbb::task
2767  {
2768  TaskEntryPoint (TaskDescriptor<RT> &task_descriptor)
2769  :
2771  {}
2772 
2773  virtual tbb::task *execute ()
2774  {
2775  // call the function object and put the return value into the
2776  // proper place
2777  try
2778  {
2779  call (task_descriptor.function, task_descriptor.ret_val);
2780  }
2781  catch (const std::exception &exc)
2782  {
2783  internal::handle_std_exception (exc);
2784  }
2785  catch (...)
2786  {
2787  internal::handle_unknown_exception ();
2788  }
2789  return 0;
2790  }
2791 
2795  TaskDescriptor<RT> &task_descriptor;
2796  };
2797 
2819  template <typename RT>
2820  struct TaskDescriptor
2821  {
2822  private:
2826  std_cxx11::function<RT ()> function;
2827 
2836  tbb::task *task;
2837 
2841  return_value<RT> ret_val;
2842 
2846  bool task_is_done;
2847 
2848  public:
2849 
2853  TaskDescriptor (const std_cxx11::function<RT ()> &function);
2854 
2860  TaskDescriptor ();
2861 
2866  TaskDescriptor (const TaskDescriptor &);
2867 
2871  ~TaskDescriptor ();
2872 
2877  TaskDescriptor &
2878  operator = (const TaskDescriptor &);
2879 
2886  void queue_task ();
2887 
2893  void join ();
2894 
2895 
2896  template <typename> friend struct TaskEntryPoint;
2897  friend class ::Threads::Task<RT>;
2898  };
2899 
2900 
2901 
2902  template <typename RT>
2903  inline
2904  TaskDescriptor<RT>::TaskDescriptor (const std_cxx11::function<RT ()> &function)
2905  :
2906  function (function),
2907  task(NULL),
2908  task_is_done (false)
2909  {}
2910 
2911 
2912  template <typename RT>
2913  inline
2914  void
2915  TaskDescriptor<RT>::queue_task ()
2916  {
2917  // use the pattern described in the TBB book on pages 230/231
2918  // ("Start a large task in parallel with the main program")
2919  task = new (tbb::task::allocate_root()) tbb::empty_task;
2920  task->set_ref_count (2);
2921 
2922  tbb::task *worker = new (task->allocate_child()) TaskEntryPoint<RT>(*this);
2923 
2924  // in earlier versions of the TBB, task::spawn was a regular
2925  // member function; however, in later versions, it was converted
2926  // into a static function. we could always call it as a regular member
2927  // function of *task, but that appears to confuse the NVidia nvcc
2928  // compiler. consequently, the following work-around:
2929 #if TBB_VERSION_MAJOR >= 4
2930  tbb::task::spawn (*worker);
2931 #else
2932  task->spawn (*worker);
2933 #endif
2934  }
2935 
2936 
2937 
2938  template <typename RT>
2939  TaskDescriptor<RT>::TaskDescriptor ()
2940  :
2941  task_is_done (false)
2942  {
2943  Assert (false, ExcInternalError());
2944  }
2945 
2946 
2947 
2948  template <typename RT>
2949  TaskDescriptor<RT>::TaskDescriptor (const TaskDescriptor &)
2950  :
2951  task_is_done (false)
2952  {
2953  // we shouldn't be getting here -- task descriptors
2954  // can't be copied
2955  Assert (false, ExcInternalError());
2956  }
2957 
2958 
2959 
2960  template <typename RT>
2961  inline
2962  TaskDescriptor<RT>::~TaskDescriptor ()
2963  {
2964  // wait for the task to complete for sure
2965  join ();
2966 
2967  // now destroy the empty task structure. the book recommends to
2968  // spawn it as well and let the scheduler destroy the object
2969  // when done, but this has the disadvantage that the scheduler
2970  // may not get to actually finishing the task before it goes out
2971  // of scope (at the end of the program, or if a thread is done
2972  // on which it was run) and then we would get a hard-to-decipher
2973  // warning about unfinished tasks when the scheduler "goes out
2974  // of the arena". rather, let's explicitly destroy the empty
2975  // task object. before that, make sure that the task has been
2976  // shut down, expressed by a zero reference count
2977  AssertNothrow (task != 0, ExcInternalError());
2978  AssertNothrow (task->ref_count()==0, ExcInternalError());
2979  task->destroy (*task);
2980  }
2981 
2982 
2983  template <typename RT>
2984  TaskDescriptor<RT> &
2985  TaskDescriptor<RT>::operator = (const TaskDescriptor &)
2986  {
2987  // we shouldn't be getting here -- task descriptors
2988  // can't be copied
2989  Assert (false, ExcInternalError());
2990  return *this;
2991  }
2992 
2993 
2994  template <typename RT>
2995  inline
2996  void
2997  TaskDescriptor<RT>::join ()
2998  {
2999  // if the task is already done, just return. this makes sure we
3000  // call tbb::Task::wait_for_all() exactly once, as required by
3001  // TBB. we could also get the reference count of task for doing
3002  // this, but that is usually slower. note that this does not
3003  // work when the thread calling this function is not the same as
3004  // the one that initialized the task.
3005  //
3006  // TODO: can we assert that no other thread tries to end the
3007  // task?
3008  if (task_is_done == true)
3009  return;
3010 
3011  // let TBB wait for the task to complete.
3012  task_is_done = true;
3013  task->wait_for_all();
3014  }
3015 
3016 
3017 
3018 #else // no threading enabled
3019 
3024  template <typename RT>
3025  struct TaskDescriptor
3026  {
3030  return_value<RT> ret_val;
3031 
3036  TaskDescriptor (const std_cxx11::function<RT ()> &function)
3037  {
3038  call (function, ret_val);
3039  }
3040 
3045  static void join () {}
3046 
3051  static void queue_task () {}
3052  };
3053 
3054 #endif
3055 
3056  }
3057 
3058 
3059 
3070  template <typename RT = void>
3071  class Task
3072  {
3073  public:
3081  Task (const std_cxx11::function<RT ()> &function_object)
3082  {
3083  // create a task descriptor and tell it to queue itself up with
3084  // the scheduling system
3085  task_descriptor.reset (new internal::TaskDescriptor<RT>(function_object));
3086  task_descriptor->queue_task ();
3087  }
3088 
3089 
3096  Task (const Task<RT> &t)
3097  :
3099  {}
3100 
3101 
3110  Task () {}
3111 
3123  void join () const
3124  {
3126  task_descriptor->join ();
3127  }
3128 
3141  bool joinable () const
3142  {
3143  return (task_descriptor !=
3144  std_cxx11::shared_ptr<internal::TaskDescriptor<RT> >());
3145  }
3146 
3147 
3159  {
3160  join ();
3161  return task_descriptor->ret_val.get();
3162  }
3163 
3164 
3170  bool operator == (const Task &t) const
3171  {
3173  return task_descriptor == t.task_descriptor;
3174  }
3175 
3185  "The current object is not associated with a task that "
3186  "can be joined. It may have been detached, or you "
3187  "may have already joined it in the past.");
3189  private:
3195  std_cxx11::shared_ptr<internal::TaskDescriptor<RT> > task_descriptor;
3196  };
3197 
3198 
3199 
3208  template <typename RT>
3209  inline
3210  Task<RT>
3211  new_task (const std_cxx11::function<RT ()> &function)
3212  {
3213  return Task<RT>(function);
3214  }
3215 
3216 
3217 #ifdef DEAL_II_WITH_CXX11
3218 
3282  template <typename FunctionObjectType>
3283  inline
3284  auto
3285  new_task (FunctionObjectType function_object)
3287  {
3288  typedef decltype(function_object()) return_type;
3289  return Task<return_type>(std_cxx11::function<return_type ()>(function_object));
3290  }
3291 
3292 #endif
3293 
3300  template <typename RT>
3301  inline
3302  Task<RT>
3303  new_task (RT (*fun_ptr)())
3304  {
3305  return new_task (std_cxx11::function<RT ()>(fun_ptr));
3306  }
3307 
3308 
3315  template <typename RT, typename C>
3316  inline
3317  Task<RT>
3318  new_task (RT (C::*fun_ptr)(),
3319  typename identity<C>::type &c)
3320  {
3321  return
3322  new_task (std_cxx11::function<RT ()>
3323  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c))));
3324  }
3325 
3326 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3327 
3333  template <typename RT, typename C>
3334  inline
3335  Task<RT>
3336  new_task (RT (C::*fun_ptr)() const,
3337  const typename identity<C>::type &c)
3338  {
3339  return
3340  new_task (std_cxx11::function<RT ()>
3341  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c))));
3342  }
3343 #endif
3344 
3345 
3346 
3347 // ----------- thread starters for unary functions
3348 
3355  template <typename RT, typename Arg1>
3356  inline
3357  Task<RT>
3358  new_task (RT (*fun_ptr)(Arg1),
3359  typename identity<Arg1>::type arg1)
3360  {
3361  return
3362  new_task (std_cxx11::function<RT ()>
3363  (std_cxx11::bind(fun_ptr,
3365  }
3366 
3367 
3368 
3375  template <typename RT, typename C, typename Arg1>
3376  inline
3377  Task<RT>
3378  new_task (RT (C::*fun_ptr)(Arg1),
3379  typename identity<C>::type &c,
3380  typename identity<Arg1>::type arg1)
3381  {
3382  return
3383  new_task (std_cxx11::function<RT ()>
3384  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3386  }
3387 
3388 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3389 
3395  template <typename RT, typename C, typename Arg1>
3396  inline
3397  Task<RT>
3398  new_task (RT (C::*fun_ptr)(Arg1) const,
3399  typename identity<const C>::type &c,
3400  typename identity<Arg1>::type arg1)
3401  {
3402  return
3403  new_task (std_cxx11::function<RT ()>
3404  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3406  }
3407 #endif
3408 
3409 // ----------- thread starters for binary functions
3410 
3417  template <typename RT, typename Arg1, typename Arg2>
3418  inline
3419  Task<RT>
3420  new_task (RT (*fun_ptr)(Arg1,Arg2),
3421  typename identity<Arg1>::type arg1,
3422  typename identity<Arg2>::type arg2)
3423  {
3424  return
3425  new_task (std_cxx11::function<RT ()>
3426  (std_cxx11::bind(fun_ptr,
3429  }
3430 
3431 
3432 
3439  template <typename RT, typename C, typename Arg1, typename Arg2>
3440  inline
3441  Task<RT>
3442  new_task (RT (C::*fun_ptr)(Arg1,Arg2),
3443  typename identity<C>::type &c,
3444  typename identity<Arg1>::type arg1,
3445  typename identity<Arg2>::type arg2)
3446  {
3447  return
3448  new_task (std_cxx11::function<RT ()>
3449  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3452  }
3453 
3454 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3455 
3461  template <typename RT, typename C, typename Arg1, typename Arg2>
3462  inline
3463  Task<RT>
3464  new_task (RT (C::*fun_ptr)(Arg1,Arg2) const,
3465  typename identity<const C>::type &c,
3466  typename identity<Arg1>::type arg1,
3467  typename identity<Arg2>::type arg2)
3468  {
3469  return
3470  new_task (std_cxx11::function<RT ()>
3471  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3474  }
3475 #endif
3476 
3477 // ----------- thread starters for ternary functions
3478 
3485  template <typename RT,
3486  typename Arg1, typename Arg2, typename Arg3>
3487  inline
3488  Task<RT>
3489  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3),
3490  typename identity<Arg1>::type arg1,
3491  typename identity<Arg2>::type arg2,
3492  typename identity<Arg3>::type arg3)
3493  {
3494  return
3495  new_task (std_cxx11::function<RT ()>
3496  (std_cxx11::bind(fun_ptr,
3500  }
3501 
3502 
3503 
3510  template <typename RT, typename C,
3511  typename Arg1, typename Arg2, typename Arg3>
3512  inline
3513  Task<RT>
3514  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3),
3515  typename identity<C>::type &c,
3516  typename identity<Arg1>::type arg1,
3517  typename identity<Arg2>::type arg2,
3518  typename identity<Arg3>::type arg3)
3519  {
3520  return
3521  new_task (std_cxx11::function<RT ()>
3522  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3526  }
3527 
3528 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3529 
3535  template <typename RT, typename C,
3536  typename Arg1, typename Arg2, typename Arg3>
3537  inline
3538  Task<RT>
3539  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3) const,
3540  typename identity<const C>::type &c,
3541  typename identity<Arg1>::type arg1,
3542  typename identity<Arg2>::type arg2,
3543  typename identity<Arg3>::type arg3)
3544  {
3545  return
3546  new_task (std_cxx11::function<RT ()>
3547  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3551  }
3552 #endif
3553 
3554 
3555 // ----------- thread starters for functions with 4 arguments
3556 
3563  template <typename RT,
3564  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3565  inline
3566  Task<RT>
3567  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
3568  typename identity<Arg1>::type arg1,
3569  typename identity<Arg2>::type arg2,
3570  typename identity<Arg3>::type arg3,
3571  typename identity<Arg4>::type arg4)
3572  {
3573  return
3574  new_task (std_cxx11::function<RT ()>
3575  (std_cxx11::bind(fun_ptr,
3580  }
3581 
3582 
3583 
3590  template <typename RT, typename C,
3591  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3592  inline
3593  Task<RT>
3594  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4),
3595  typename identity<C>::type &c,
3596  typename identity<Arg1>::type arg1,
3597  typename identity<Arg2>::type arg2,
3598  typename identity<Arg3>::type arg3,
3599  typename identity<Arg4>::type arg4)
3600  {
3601  return
3602  new_task (std_cxx11::function<RT ()>
3603  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3608  }
3609 
3610 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3611 
3617  template <typename RT, typename C,
3618  typename Arg1, typename Arg2, typename Arg3, typename Arg4>
3619  inline
3620  Task<RT>
3621  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4) const,
3622  typename identity<const C>::type &c,
3623  typename identity<Arg1>::type arg1,
3624  typename identity<Arg2>::type arg2,
3625  typename identity<Arg3>::type arg3,
3626  typename identity<Arg4>::type arg4)
3627  {
3628  return
3629  new_task (std_cxx11::function<RT ()>
3630  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3635  }
3636 #endif
3637 
3638 // ----------- thread starters for functions with 5 arguments
3639 
3646  template <typename RT,
3647  typename Arg1, typename Arg2, typename Arg3,
3648  typename Arg4, typename Arg5>
3649  inline
3650  Task<RT>
3651  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
3652  typename identity<Arg1>::type arg1,
3653  typename identity<Arg2>::type arg2,
3654  typename identity<Arg3>::type arg3,
3655  typename identity<Arg4>::type arg4,
3656  typename identity<Arg5>::type arg5)
3657  {
3658  return
3659  new_task (std_cxx11::function<RT ()>
3660  (std_cxx11::bind(fun_ptr,
3666  }
3667 
3668 
3669 
3676  template <typename RT, typename C,
3677  typename Arg1, typename Arg2, typename Arg3,
3678  typename Arg4, typename Arg5>
3679  inline
3680  Task<RT>
3681  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5),
3682  typename identity<C>::type &c,
3683  typename identity<Arg1>::type arg1,
3684  typename identity<Arg2>::type arg2,
3685  typename identity<Arg3>::type arg3,
3686  typename identity<Arg4>::type arg4,
3687  typename identity<Arg5>::type arg5)
3688  {
3689  return
3690  new_task (std_cxx11::function<RT ()>
3691  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3697  }
3698 
3699 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3700 
3706  template <typename RT, typename C,
3707  typename Arg1, typename Arg2, typename Arg3,
3708  typename Arg4, typename Arg5>
3709  inline
3710  Task<RT>
3711  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5) const,
3712  typename identity<const C>::type &c,
3713  typename identity<Arg1>::type arg1,
3714  typename identity<Arg2>::type arg2,
3715  typename identity<Arg3>::type arg3,
3716  typename identity<Arg4>::type arg4,
3717  typename identity<Arg5>::type arg5)
3718  {
3719  return
3720  new_task (std_cxx11::function<RT ()>
3721  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3727  }
3728 #endif
3729 
3730 // ----------- thread starters for functions with 6 arguments
3731 
3738  template <typename RT,
3739  typename Arg1, typename Arg2, typename Arg3,
3740  typename Arg4, typename Arg5, typename Arg6>
3741  inline
3742  Task<RT>
3743  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
3744  typename identity<Arg1>::type arg1,
3745  typename identity<Arg2>::type arg2,
3746  typename identity<Arg3>::type arg3,
3747  typename identity<Arg4>::type arg4,
3748  typename identity<Arg5>::type arg5,
3749  typename identity<Arg6>::type arg6)
3750  {
3751  return
3752  new_task (std_cxx11::function<RT ()>
3753  (std_cxx11::bind(fun_ptr,
3760  }
3761 
3762 
3763 
3770  template <typename RT, typename C,
3771  typename Arg1, typename Arg2, typename Arg3,
3772  typename Arg4, typename Arg5, typename Arg6>
3773  inline
3774  Task<RT>
3775  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6),
3776  typename identity<C>::type &c,
3777  typename identity<Arg1>::type arg1,
3778  typename identity<Arg2>::type arg2,
3779  typename identity<Arg3>::type arg3,
3780  typename identity<Arg4>::type arg4,
3781  typename identity<Arg5>::type arg5,
3782  typename identity<Arg6>::type arg6)
3783  {
3784  return
3785  new_task (std_cxx11::function<RT ()>
3786  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3793  }
3794 
3795 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3796 
3802  template <typename RT, typename C,
3803  typename Arg1, typename Arg2, typename Arg3,
3804  typename Arg4, typename Arg5, typename Arg6>
3805  inline
3806  Task<RT>
3807  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6) const,
3808  typename identity<const C>::type &c,
3809  typename identity<Arg1>::type arg1,
3810  typename identity<Arg2>::type arg2,
3811  typename identity<Arg3>::type arg3,
3812  typename identity<Arg4>::type arg4,
3813  typename identity<Arg5>::type arg5,
3814  typename identity<Arg6>::type arg6)
3815  {
3816  return
3817  new_task (std_cxx11::function<RT ()>
3818  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3825  }
3826 #endif
3827 
3828 // ----------- thread starters for functions with 7 arguments
3829 
3836  template <typename RT,
3837  typename Arg1, typename Arg2, typename Arg3,
3838  typename Arg4, typename Arg5, typename Arg6,
3839  typename Arg7>
3840  inline
3841  Task<RT>
3842  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
3843  typename identity<Arg1>::type arg1,
3844  typename identity<Arg2>::type arg2,
3845  typename identity<Arg3>::type arg3,
3846  typename identity<Arg4>::type arg4,
3847  typename identity<Arg5>::type arg5,
3848  typename identity<Arg6>::type arg6,
3849  typename identity<Arg7>::type arg7)
3850  {
3851  return
3852  new_task (std_cxx11::function<RT ()>
3853  (std_cxx11::bind(fun_ptr,
3861  }
3862 
3863 
3864 
3871  template <typename RT, typename C,
3872  typename Arg1, typename Arg2, typename Arg3,
3873  typename Arg4, typename Arg5, typename Arg6,
3874  typename Arg7>
3875  inline
3876  Task<RT>
3877  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7),
3878  typename identity<C>::type &c,
3879  typename identity<Arg1>::type arg1,
3880  typename identity<Arg2>::type arg2,
3881  typename identity<Arg3>::type arg3,
3882  typename identity<Arg4>::type arg4,
3883  typename identity<Arg5>::type arg5,
3884  typename identity<Arg6>::type arg6,
3885  typename identity<Arg7>::type arg7)
3886  {
3887  return
3888  new_task (std_cxx11::function<RT ()>
3889  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
3897  }
3898 
3899 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
3900 
3906  template <typename RT, typename C,
3907  typename Arg1, typename Arg2, typename Arg3,
3908  typename Arg4, typename Arg5, typename Arg6,
3909  typename Arg7>
3910  inline
3911  Task<RT>
3912  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7) const,
3913  typename identity<const C>::type &c,
3914  typename identity<Arg1>::type arg1,
3915  typename identity<Arg2>::type arg2,
3916  typename identity<Arg3>::type arg3,
3917  typename identity<Arg4>::type arg4,
3918  typename identity<Arg5>::type arg5,
3919  typename identity<Arg6>::type arg6,
3920  typename identity<Arg7>::type arg7)
3921  {
3922  return
3923  new_task (std_cxx11::function<RT ()>
3924  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
3932  }
3933 #endif
3934 
3935 // ----------- thread starters for functions with 8 arguments
3936 
3943  template <typename RT,
3944  typename Arg1, typename Arg2, typename Arg3,
3945  typename Arg4, typename Arg5, typename Arg6,
3946  typename Arg7, typename Arg8>
3947  inline
3948  Task<RT>
3949  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3950  Arg6,Arg7,Arg8),
3951  typename identity<Arg1>::type arg1,
3952  typename identity<Arg2>::type arg2,
3953  typename identity<Arg3>::type arg3,
3954  typename identity<Arg4>::type arg4,
3955  typename identity<Arg5>::type arg5,
3956  typename identity<Arg6>::type arg6,
3957  typename identity<Arg7>::type arg7,
3958  typename identity<Arg8>::type arg8)
3959  {
3960  return
3961  new_task (std_cxx11::function<RT ()>
3962  (std_cxx11::bind(fun_ptr,
3971  }
3972 
3973 
3974 
3981  template <typename RT, typename C,
3982  typename Arg1, typename Arg2, typename Arg3,
3983  typename Arg4, typename Arg5, typename Arg6,
3984  typename Arg7, typename Arg8>
3985  inline
3986  Task<RT>
3987  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
3988  Arg6,Arg7,Arg8),
3989  typename identity<C>::type &c,
3990  typename identity<Arg1>::type arg1,
3991  typename identity<Arg2>::type arg2,
3992  typename identity<Arg3>::type arg3,
3993  typename identity<Arg4>::type arg4,
3994  typename identity<Arg5>::type arg5,
3995  typename identity<Arg6>::type arg6,
3996  typename identity<Arg7>::type arg7,
3997  typename identity<Arg8>::type arg8)
3998  {
3999  return
4000  new_task (std_cxx11::function<RT ()>
4001  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
4010  }
4011 
4012 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4013 
4019  template <typename RT, typename C,
4020  typename Arg1, typename Arg2, typename Arg3,
4021  typename Arg4, typename Arg5, typename Arg6,
4022  typename Arg7, typename Arg8>
4023  inline
4024  Task<RT>
4025  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
4026  Arg6,Arg7,Arg8) const,
4027  typename identity<const C>::type &c,
4028  typename identity<Arg1>::type arg1,
4029  typename identity<Arg2>::type arg2,
4030  typename identity<Arg3>::type arg3,
4031  typename identity<Arg4>::type arg4,
4032  typename identity<Arg5>::type arg5,
4033  typename identity<Arg6>::type arg6,
4034  typename identity<Arg7>::type arg7,
4035  typename identity<Arg8>::type arg8)
4036  {
4037  return
4038  new_task (std_cxx11::function<RT ()>
4039  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
4048  }
4049 #endif
4050 
4051 // ----------- thread starters for functions with 9 arguments
4052 
4059  template <typename RT,
4060  typename Arg1, typename Arg2, typename Arg3,
4061  typename Arg4, typename Arg5, typename Arg6,
4062  typename Arg7, typename Arg8, typename Arg9>
4063  inline
4064  Task<RT>
4065  new_task (RT (*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
4066  Arg6,Arg7,Arg8,Arg9),
4067  typename identity<Arg1>::type arg1,
4068  typename identity<Arg2>::type arg2,
4069  typename identity<Arg3>::type arg3,
4070  typename identity<Arg4>::type arg4,
4071  typename identity<Arg5>::type arg5,
4072  typename identity<Arg6>::type arg6,
4073  typename identity<Arg7>::type arg7,
4074  typename identity<Arg8>::type arg8,
4075  typename identity<Arg9>::type arg9)
4076  {
4077  return
4078  new_task (std_cxx11::function<RT ()>
4079  (std_cxx11::bind(fun_ptr,
4089  }
4090 
4091 
4092 
4099  template <typename RT, typename C,
4100  typename Arg1, typename Arg2, typename Arg3,
4101  typename Arg4, typename Arg5, typename Arg6,
4102  typename Arg7, typename Arg8, typename Arg9>
4103  inline
4104  Task<RT>
4105  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
4106  Arg6,Arg7,Arg8,Arg9),
4107  typename identity<C>::type &c,
4108  typename identity<Arg1>::type arg1,
4109  typename identity<Arg2>::type arg2,
4110  typename identity<Arg3>::type arg3,
4111  typename identity<Arg4>::type arg4,
4112  typename identity<Arg5>::type arg5,
4113  typename identity<Arg6>::type arg6,
4114  typename identity<Arg7>::type arg7,
4115  typename identity<Arg8>::type arg8,
4116  typename identity<Arg9>::type arg9)
4117  {
4118  return
4119  new_task (std_cxx11::function<RT ()>
4120  (std_cxx11::bind(fun_ptr, std_cxx11::ref(c),
4130  }
4131 
4132 #ifndef DEAL_II_CONST_MEMBER_DEDUCTION_BUG
4133 
4139  template <typename RT, typename C,
4140  typename Arg1, typename Arg2, typename Arg3,
4141  typename Arg4, typename Arg5, typename Arg6,
4142  typename Arg7, typename Arg8, typename Arg9>
4143  inline
4144  Task<RT>
4145  new_task (RT (C::*fun_ptr)(Arg1,Arg2,Arg3,Arg4,Arg5,
4146  Arg6,Arg7,Arg8,Arg9) const,
4147  typename identity<const C>::type &c,
4148  typename identity<Arg1>::type arg1,
4149  typename identity<Arg2>::type arg2,
4150  typename identity<Arg3>::type arg3,
4151  typename identity<Arg4>::type arg4,
4152  typename identity<Arg5>::type arg5,
4153  typename identity<Arg6>::type arg6,
4154  typename identity<Arg7>::type arg7,
4155  typename identity<Arg8>::type arg8,
4156  typename identity<Arg9>::type arg9)
4157  {
4158  return
4159  new_task (std_cxx11::function<RT ()>
4160  (std_cxx11::bind(fun_ptr, std_cxx11::cref(c),
4170  }
4171 #endif
4172 
4173 
4174 // ------------------------ TaskGroup -------------------------------------
4175 
4189  template <typename RT = void>
4191  {
4192  public:
4197  {
4198  tasks.push_back (t);
4199  return *this;
4200  }
4201 
4208  void join_all () const
4209  {
4210  for (typename std::list<Task<RT> >::const_iterator
4211  t=tasks.begin(); t!=tasks.end(); ++t)
4212  t->join ();
4213  }
4214 
4215  private:
4219  std::list<Task<RT> > tasks;
4220  };
4221 
4222 } // end of implementation of namespace Threads
4223 
4229 //---------------------------------------------------------------------------
4230 DEAL_II_NAMESPACE_CLOSE
4231 // end of #ifndef dealii__thread_management_h
4232 #endif
4233 //---------------------------------------------------------------------------
#define AssertNothrow(cond, exc)
Definition: exceptions.h:342
std_cxx11::condition_variable condition_variable
Task(const std_cxx11::function< RT()> &function_object)
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)
void join() const
#define AssertThrow(cond, exc)
Definition: exceptions.h:369
PosixThreadBarrier(const unsigned int count, const char *name=0, void *arg=0)
bool operator==(const Task &t) const
std::vector< std::pair< unsigned int, unsigned int > > split_interval(const unsigned int begin, const unsigned int end, const unsigned int n_intervals)
Mutex & operator=(const Mutex &)
DummyBarrier(const unsigned int count, const char *name=0, void *arg=0)
static ::ExceptionBase & ExcNoTask()
#define DeclException1(Exception1, type1, outsequence)
Definition: exceptions.h:564
Thread< RT > new_thread(const std_cxx11::function< RT()> &function)
#define Assert(cond, exc)
Definition: exceptions.h:313
#define DeclExceptionMsg(Exception, defaulttext)
Definition: exceptions.h:553
unsigned int n_existing_threads()
bool joinable() const
void wait(DummyThreadMutex &) const
std_cxx11::shared_ptr< internal::ThreadDescriptor< RT > > thread_descriptor
bool operator==(const Thread &t) const
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)
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
static ::ExceptionBase & ExcInternalError()
static ::ExceptionBase & ExcBarrierSizeNotUseful(int arg1)