]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Put the new multithreading scheme in place.
authorwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 13 Apr 2000 16:45:20 +0000 (16:45 +0000)
committerwolf <wolf@0785d39b-7218-0410-832d-ea1e28bc413d>
Thu, 13 Apr 2000 16:45:20 +0000 (16:45 +0000)
git-svn-id: https://svn.dealii.org/trunk@2714 0785d39b-7218-0410-832d-ea1e28bc413d

12 files changed:
deal.II/base/include/base/thread_management.h [new file with mode: 0644]
deal.II/base/include/base/thread_manager.h [deleted file]
deal.II/base/source/thread_management.cc [new file with mode: 0644]
deal.II/deal.II/source/numerics/data_out.cc
deal.II/deal.II/source/numerics/error_estimator.cc
deal.II/deal.II/source/numerics/time_dependent.cc
deal.II/doc/news/2000/02.html [new file with mode: 0644]
deal.II/doc/news/2000/c-3-0.html
deal.II/doc/news/news.html
deal.II/lac/include/lac/sparse_matrix.h
deal.II/lac/include/lac/sparse_matrix.templates.h
deal.II/lac/include/lac/sparse_vanka.templates.h

diff --git a/deal.II/base/include/base/thread_management.h b/deal.II/base/include/base/thread_management.h
new file mode 100644 (file)
index 0000000..7a1ad42
--- /dev/null
@@ -0,0 +1,3056 @@
+//----------------------------  thread_management.h  ---------------------------
+//    $Id$
+//    Version: $Name$
+//
+//    Copyright (C) 2000 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//----------------------------  thread_management.h  ---------------------------
+#ifndef __deal2__thread_management_h
+#define __deal2__thread_management_h
+
+
+#ifdef DEAL_II_USE_MT
+
+#include <base/exceptions.h>
+#include <ace/Thread_Manager.h>
+#include <ace/Synch.h>
+
+#include <string>
+#include <utility>
+#include <vector>
+#include <iterator>
+
+
+
+
+namespace Threads 
+{
+                                  // forward declarations
+  class FunDataBase;
+
+
+/**
+ * Class used to store a pointer temporarily and delete the object
+ * pointed to upon destruction of this object. For more information on
+ * use and internals of this class see the report on this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  class FunEncapsulation
+  {
+    private:
+                                      /**
+                                       * Default constructor. Construct
+                                       * the object empty, i.e. set
+                                       * #data==0#. Since this is not
+                                       * very useful, disallow it by
+                                       * declaring this constructor
+                                       * #private#.
+                                       */
+      FunEncapsulation ();
+
+    public:
+                                      /**
+                                       * Copy constructor. Clone the
+                                       * object pointed to by
+                                       * #fun_data.fun_data_base#.
+                                       */
+      FunEncapsulation (const FunEncapsulation &fun_encapsulation);
+
+                                      /**
+                                       * This is the usual
+                                       * constructor. Set #fun_data_base# to
+                                       * #fun_data_base#. This is what
+                                       * the #fun_data_*# functions
+                                       * use.
+                                       */
+      FunEncapsulation (FunDataBase *fun_data_base);
+
+                                      /**
+                                       * Destructor. Delete the object
+                                       * pointed to by #fun_data_base#.
+                                       */
+      ~FunEncapsulation ();
+
+                                      /**
+                                       * Copy another object of this
+                                       * type by cloning its #fun_data_base#
+                                       * object.
+                                       */
+      const FunEncapsulation & operator = (const FunEncapsulation &fun_encapsulation);
+    
+                                      /**
+                                       * Pointer to the object which
+                                       * contains all the parameters.
+                                       */
+      const FunDataBase * fun_data_base;
+  };
+
+
+
+/**
+ * Abstract base class for those classes that actually store
+ * parameters of functions. For more information on use and internals
+ * of this class see the report on this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  class FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a
+                                       * function that satifies the
+                                       * requirements of thread entry
+                                       * points.
+                                       */
+      typedef void * (*ThreadEntryPoint) (void *);
+
+                                      /**
+                                       * Default constructor. Store the
+                                       * pointer to the function which
+                                       * we will use as thread entry
+                                       * point for the derived class.
+                                       */
+      FunDataBase (const ThreadEntryPoint thread_entry_point);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      FunDataBase (const FunDataBase &);
+
+                                      /**
+                                       * Destructor. Needs to be
+                                       * virtual to make destruction of
+                                       * derived classes through base
+                                       * class pointers.
+                                       */
+      virtual ~FunDataBase ();
+
+                                      /**
+                                       * Virtual constructor. Needed to
+                                       * copy an object of which we
+                                       * only have a pointer to the
+                                       * base class. Copying such
+                                       * objects is necessary to
+                                       * guarantee memory consistency.
+                                       */
+      virtual FunDataBase * clone () const = 0;
+
+                                      /**
+                                       * Lock to be used when starting
+                                       * a thread and which is released
+                                       * after the data of this object
+                                       * is copied and therefore no
+                                       * more needed. This ensures that
+                                       * no data is deleted when it is
+                                       * still in use.
+                                       */
+      mutable ACE_Thread_Mutex lock;
+    
+    private:
+                                      /**
+                                       * Pointer to the thread entry
+                                       * point function. The address of
+                                       * that function is passed from
+                                       * the derived classes to the
+                                       * constructor of this class.
+                                       */
+      ThreadEntryPoint thread_entry_point;
+
+                                      /**
+                                       * Make the thread starter
+                                       * function a friend, since it
+                                       * needs to have access to the
+                                       * #thread_entry_point# variable.
+                                       */
+      friend void spawn (ACE_Thread_Manager       &thread_manager,
+                        const FunEncapsulation   &fun_data);
+  };
+
+
+
+/**
+ * Class to store the parameters of a void function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <typename RetType>
+  class FunData0 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (*FunPtr) ();
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      FunData0 (FunPtr fun_ptr);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      FunData0 (const FunData0 &fun_data0);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef FunData0<RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           *
+                                           * Since the function in
+                                           * question here does not
+                                           * take parameters, this
+                                           * function also does
+                                           * nothing. It is only
+                                           * present for
+                                           * orthogonality of thread
+                                           * creation.
+                                           */
+         FunEncapsulation collect_args ();
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+
+
+/**
+ * Class to store the parameters of a unary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <typename Arg1, typename RetType>
+  class FunData1 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (*FunPtr) (Arg1);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      FunData1 (FunPtr fun_ptr,
+               Arg1   arg1);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      FunData1 (const FunData1 &fun_data1);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef FunData1<Arg1,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Arg1 arg1);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+
+
+/**
+ * Class to store the parameters of a binary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <typename Arg1, typename Arg2, typename RetType>
+  class FunData2 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (*FunPtr) (Arg1, Arg2);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      FunData2 (FunPtr fun_ptr,
+               Arg1   arg1,
+               Arg2   arg2);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      FunData2 (const FunData2 &fun_data2);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+      Arg2   arg2;
+      
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef FunData2<Arg1,Arg2,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Arg1 arg1,
+                                        Arg2 arg2);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+  
+/**
+ * Class to store the parameters of a ternary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  class FunData3 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      FunData3 (FunPtr fun_ptr,
+               Arg1   arg1,
+               Arg2   arg2,
+               Arg3   arg3);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      FunData3 (const FunData3 &fun_data3);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+      Arg2   arg2;
+      Arg3   arg3;
+      
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef FunData3<Arg1,Arg2,Arg3,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Arg1 arg1,
+                                        Arg2 arg2,
+                                        Arg3 arg3);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+
+/**
+ * Class to store the parameters of a quaternary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  class FunData4 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      FunData4 (FunPtr fun_ptr,
+               Arg1   arg1,
+               Arg2   arg2,
+               Arg3   arg3,
+               Arg4   arg4);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      FunData4 (const FunData4 &fun_data4);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+      Arg2   arg2;
+      Arg3   arg3;
+      Arg4   arg4;
+      
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Arg1 arg1,
+                                        Arg2 arg2,
+                                        Arg3 arg3,
+                                        Arg4 arg4);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+
+
+/**
+ * Class to store the parameters of a quintary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  class FunData5 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      FunData5 (FunPtr fun_ptr,
+               Arg1   arg1,
+               Arg2   arg2,
+               Arg3   arg3,
+               Arg4   arg4,
+               Arg5   arg5);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      FunData5 (const FunData5 &fun_data5);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+      Arg2   arg2;
+      Arg3   arg3;
+      Arg4   arg4;
+      Arg5   arg5;
+      
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Arg1 arg1,
+                                        Arg2 arg2,
+                                        Arg3 arg3,
+                                        Arg4 arg4,
+                                        Arg5 arg5);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+  
+  
+/**
+ * Class to store the parameters of a void function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <class Class, typename RetType>
+  class MemFunData0 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (Class::*FunPtr) ();
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      MemFunData0 (FunPtr fun_ptr,
+                  Class *object);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      MemFunData0 (const MemFunData0 &fun_data0);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Pointer to the object which
+                                       * we shall work on.
+                                       */
+      Class *object;
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef MemFunData0<Class,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Class *object);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+
+
+/**
+ * Class to store the parameters of a unary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <class Class, typename Arg1, typename RetType>
+  class MemFunData1 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (Class::*FunPtr) (Arg1);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      MemFunData1 (FunPtr fun_ptr,
+                  Class *object,
+                  Arg1   arg1);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      MemFunData1 (const MemFunData1 &fun_data1);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Pointer to the object which
+                                       * we shall work on.
+                                       */
+      Class *object;
+      
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef MemFunData1<Class,Arg1,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Class *object,
+                                        Arg1 arg1);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+
+
+/**
+ * Class to store the parameters of a binary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <class Class, typename Arg1, typename Arg2, typename RetType>
+  class MemFunData2 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (Class::*FunPtr) (Arg1, Arg2);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      MemFunData2 (FunPtr fun_ptr,
+                  Class *object,
+                  Arg1   arg1,
+                  Arg2   arg2);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      MemFunData2 (const MemFunData2 &fun_data2);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Pointer to the object which
+                                       * we shall work on.
+                                       */
+      Class *object;
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+      Arg2   arg2;
+      
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef MemFunData2<Class,Arg1,Arg2,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Class *object,
+                                        Arg1 arg1,
+                                        Arg2 arg2);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+  
+/**
+ * Class to store the parameters of a ternary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  class MemFunData3 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (Class::*FunPtr) (Arg1, Arg2, Arg3);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      MemFunData3 (FunPtr fun_ptr,
+                  Class *object,
+                  Arg1   arg1,
+                  Arg2   arg2,
+                  Arg3   arg3);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      MemFunData3 (const MemFunData3 &fun_data3);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Pointer to the object which
+                                       * we shall work on.
+                                       */
+      Class *object;
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+      Arg2   arg2;
+      Arg3   arg3;
+      
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Class *object,
+                                        Arg1 arg1,
+                                        Arg2 arg2,
+                                        Arg3 arg3);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+
+
+/**
+ * Class to store the parameters of a quaternary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  class MemFunData4 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (Class::*FunPtr) (Arg1, Arg2, Arg3, Arg4);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      MemFunData4 (FunPtr fun_ptr,
+                  Class *object,
+                  Arg1   arg1,
+                  Arg2   arg2,
+                  Arg3   arg3,
+                  Arg4   arg4);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      MemFunData4 (const MemFunData4 &fun_data4);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Pointer to the object which
+                                       * we shall work on.
+                                       */
+      Class *object;
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+      Arg2   arg2;
+      Arg3   arg3;
+      Arg4   arg4;
+      
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Class *object,
+                                        Arg1 arg1,
+                                        Arg2 arg2,
+                                        Arg3 arg3,
+                                        Arg4 arg4);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+
+
+
+/**
+ * Class to store the parameters of a quintary function. For more
+ * information on use and internals of this class see the report on
+ * this subject.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  class MemFunData5 : public FunDataBase
+  {
+    public:
+                                      /**
+                                       * Typedef a pointer to a global
+                                       * function which we will call
+                                       * from this class.
+                                       */
+      typedef RetType (Class::*FunPtr) (Arg1, Arg2, Arg3, Arg4, Arg5);
+
+                                      /**
+                                       * Constructor. Store pointer to
+                                       * the function and the values of
+                                       * the arguments.
+                                       */
+      MemFunData5 (FunPtr fun_ptr,
+                  Class *object,
+                  Arg1   arg1,
+                  Arg2   arg2,
+                  Arg3   arg3,
+                  Arg4   arg4,
+                  Arg5   arg5);
+
+                                      /**
+                                       * Copy constructor.
+                                       */
+      MemFunData5 (const MemFunData5 &fun_data5);
+
+                                      /**
+                                       * Virtual constructor.
+                                       */
+      virtual FunDataBase * clone () const;
+
+    private:
+
+                                      /**
+                                       * Pointer to the function to be
+                                       * called and values of the
+                                       * arguments to be passed.
+                                       */
+      FunPtr fun_ptr;
+
+                                      /**
+                                       * Pointer to the object which
+                                       * we shall work on.
+                                       */
+      Class *object;
+                                      /**
+                                       * Values of the arguments of the
+                                       * function to be called.
+                                       */
+      Arg1   arg1;
+      Arg2   arg2;
+      Arg3   arg3;
+      Arg4   arg4;
+      Arg5   arg5;
+      
+                                      /**
+                                       * Static function used as entry
+                                       * point for the new thread.
+                                       */
+      static void * thread_entry_point (void *arg);
+
+                                      /**
+                                       * Helper class, used to collect
+                                       * the values of the parameters
+                                       * which we will pass to the
+                                       * function, once we know its
+                                       * type.
+                                       */
+      class ArgCollector
+      {
+       public:
+                                          /**
+                                           * Typedef the function
+                                           * pointer type of the
+                                           * underlying class to a
+                                           * local type.
+                                           */
+         typedef MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::FunPtr FunPtr;
+       
+                                          /**
+                                           * Constructor. Take and store a
+                                           * pointer to the function which
+                                           * is to be called.
+                                           */
+         ArgCollector (FunPtr fun_ptr);
+    
+                                          /**
+                                           * Take the arguments with
+                                           * which we want to call the
+                                           * function and produce and
+                                           * object of the desired type
+                                           * from that.
+                                           */
+         FunEncapsulation collect_args (Class *object,
+                                        Arg1 arg1,
+                                        Arg2 arg2,
+                                        Arg3 arg3,
+                                        Arg4 arg4,
+                                        Arg5 arg5);
+    
+       private:
+                                          /**
+                                           * Space to temporarily store
+                                           * the function pointer.
+                                           */
+         FunPtr fun_ptr;
+      };
+  };
+  
+  
+                                  /**
+                                   * Encapsulate a function pointer
+                                   * into an object with which a new
+                                   * thread can later be spawned.
+                                   * For more information on use and
+                                   * internals of this class see the
+                                   * report on this subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  FunData0<void>::ArgCollector
+  encapsulate (void (*fun_ptr)());
+
+                                  /**
+                                   * Encapsulate a function pointer
+                                   * into an object with which a new
+                                   * thread can later be spawned.
+                                   * For more information on use and
+                                   * internals of this class see the
+                                   * report on this subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <typename Arg1>
+  typename FunData1<Arg1,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1));
+
+
+                                  /**
+                                   * Encapsulate a function pointer
+                                   * into an object with which a new
+                                   * thread can later be spawned.
+                                   * For more information on use and
+                                   * internals of this class see the
+                                   * report on this subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <typename Arg1, typename Arg2>
+  typename FunData2<Arg1,Arg2,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1, Arg2));
+  
+
+                                  /**
+                                   * Encapsulate a function pointer
+                                   * into an object with which a new
+                                   * thread can later be spawned.
+                                   * For more information on use and
+                                   * internals of this class see the
+                                   * report on this subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <typename Arg1, typename Arg2, typename Arg3>
+  typename FunData3<Arg1,Arg2,Arg3,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3));
+  
+
+                                  /**
+                                   * Encapsulate a function pointer
+                                   * into an object with which a new
+                                   * thread can later be spawned.
+                                   * For more information on use and
+                                   * internals of this class see the
+                                   * report on this subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  typename FunData4<Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4));
+
+
+
+                                  /**
+                                   * Encapsulate a function pointer
+                                   * into an object with which a new
+                                   * thread can later be spawned.
+                                   * For more information on use and
+                                   * internals of this class see the
+                                   * report on this subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+  typename FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4,Arg5));
+
+
+                                  /**
+                                   * Encapsulate a member function
+                                   * pointer into an object with
+                                   * which a new thread can later be
+                                   * spawned.  For more information
+                                   * on use and internals of this
+                                   * class see the report on this
+                                   * subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <class Class>
+  typename MemFunData0<Class,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)());
+
+                                  /**
+                                   * Encapsulate a member function
+                                   * pointer into an object with
+                                   * which a new thread can later be
+                                   * spawned.  For more information
+                                   * on use and internals of this
+                                   * class see the report on this
+                                   * subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <class Class, typename Arg1>
+  typename MemFunData1<Class,Arg1,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1));
+
+
+                                  /**
+                                   * Encapsulate a member function
+                                   * pointer into an object with
+                                   * which a new thread can later be
+                                   * spawned.  For more information
+                                   * on use and internals of this
+                                   * class see the report on this
+                                   * subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <class Class, typename Arg1, typename Arg2>
+  typename MemFunData2<Class,Arg1,Arg2,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2));
+  
+
+                                  /**
+                                   * Encapsulate a member function
+                                   * pointer into an object with
+                                   * which a new thread can later be
+                                   * spawned.  For more information
+                                   * on use and internals of this
+                                   * class see the report on this
+                                   * subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <class Class, typename Arg1, typename Arg2, typename Arg3>
+  typename MemFunData3<Class,Arg1,Arg2,Arg3,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3));
+  
+
+                                  /**
+                                   * Encapsulate a member function
+                                   * pointer into an object with
+                                   * which a new thread can later be
+                                   * spawned.  For more information
+                                   * on use and internals of this
+                                   * class see the report on this
+                                   * subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  typename MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4));
+  
+
+                                  /**
+                                   * Encapsulate a member function
+                                   * pointer into an object with
+                                   * which a new thread can later be
+                                   * spawned.  For more information
+                                   * on use and internals of this
+                                   * class see the report on this
+                                   * subject.
+                                   *
+                                   * This function exists once for
+                                   * each number of parameters.
+                                   */
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+  typename MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5));
+
+
+
+                                  /**
+                                   * Spawn a new thread using the
+                                   * function and parameters
+                                   * encapsulated in #fun_data#, and
+                                   * using the given thread manager
+                                   * object.
+                                   */
+  void spawn (ACE_Thread_Manager     &thread_manager,
+             const FunEncapsulation &fun_data);
+
+
+                                  /**
+                                   * Spawn several threads at once,
+                                   * using the same parameters and
+                                   * calling the same function.
+                                   */
+  void spawn_n (ACE_Thread_Manager     &thread_manager,
+               const FunEncapsulation &fun_encapsulation,
+               const unsigned int      n_threads);
+
+
+                                  /**
+                                   * Split the range #[begin,end)#
+                                   * into #n_intervals# subintervals
+                                   * of equal size. The last interval
+                                   * will be a little bit larger, if
+                                   * the number of elements in the
+                                   * whole range is not exactly
+                                   * divisible by #n_intervals#. The
+                                   * type of the iterators has to
+                                   * fulfill the requirements of a
+                                   * forward iterator,
+                                   * i.e. #operator++# must be
+                                   * available, and of course it must
+                                   * be assignable.
+                                   *
+                                   * A list of subintervals is
+                                   * returned as a vector of pairs of
+                                   * iterators, where each pair
+                                   * denotes the range
+                                   * #[begin[i],end[i])#.
+                                   */
+  template <typename ForwardIterator>
+  vector<pair<ForwardIterator,ForwardIterator> >
+  split_range (const ForwardIterator &begin,
+              const ForwardIterator &end,
+              const unsigned int n_intervals);
+
+                                  /**
+                                   * Split the interval #[begin,end)#
+                                   * into subintervals of (almost)
+                                   * equal size. This function works
+                                   * mostly as the one before, with
+                                   * the difference that instead of
+                                   * iterators, now values are taken
+                                   * that define the whole interval.
+                                   */
+  vector<pair<unsigned int,unsigned int> >
+  split_interval (const unsigned int begin,
+                 const unsigned int end,
+                 const unsigned int n_intervals);
+  
+  
+
+/**
+ * This class is used to make some sanity checks on the numbers of
+ * objects of some types related with thread spawning, which are
+ * created and deleted. This is a helpful thing when trying to
+ * implement the data copying using #clone# functions etc, in order to
+ * avoid that there are some objects which are copied but not deleted.
+ *
+ * It basically only monitors the number of objects which is alive at
+ * each time, and complains if the number is nonzero when the counting
+ * object is deleted. Since one will probably want to use one global
+ * counter, the complaint is raised at the end of the program, and
+ * then means that somewhen within the lifetime of your program there
+ * has occured a memory leak.
+ *
+ * This class is not meant for public use.
+ *
+ * @author Wolfgang Bangerth, 2000
+ */
+  struct FunDataCounter
+  {
+                                      /**
+                                       * Constructor. Sets all
+                                       * counters to zero.
+                                       */
+      FunDataCounter ();
+      
+                                      /**
+                                       * Destructor. Check whether
+                                       * the total number of objects
+                                       * is zero, otherwise throw an
+                                       * exception.
+                                       */
+      ~FunDataCounter ();
+
+                                      /**
+                                       * Counters for the two types
+                                       * of objects which we
+                                       * presently monitor.
+                                       */
+      unsigned int n_fun_encapsulation_objects;
+      unsigned int n_fun_data_base_objects;
+
+                                      /**
+                                       * Exception
+                                       */
+      DeclException2 (ExcObjectsExist,
+                     string, int,
+                     << "There are still " << arg2 << " objects of type "
+                     << arg1 << " alive. You probably have a memory "
+                     << "leak somewhere.");
+  };
+
+};   // end declarations of namespace Threads
+
+
+
+
+
+
+
+/* ----------- implementation of functions in namespace Threads ---------- */
+namespace Threads 
+{
+
+/* ---------------------- FunData0 implementation ------------------------ */
+
+  template <typename RetType>
+  FunData0<RetType>::FunData0 (FunPtr fun_ptr) :
+                 FunDataBase (&FunData0<RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr)
+  {};
+
+
+
+  template <typename RetType>
+  FunData0<RetType>::FunData0 (const FunData0 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr)
+  {};
+
+
+
+  template <typename RetType>
+  FunDataBase *
+  FunData0<RetType>::clone () const 
+  {
+    return new FunData0 (*this);
+  };
+
+
+
+  template <typename RetType>
+  void *
+  FunData0<RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef FunData0<RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (*fun_ptr)();
+  
+    return 0;
+  };
+
+
+
+  template <typename RetType>
+  FunData0<RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+       
+
+  
+  template <typename RetType>
+  FunEncapsulation
+  FunData0<RetType>::ArgCollector::collect_args ()
+  {
+    return new FunData0<void>(fun_ptr);
+  };
+
+
+/* ---------------------- FunData1 implementation ------------------------ */
+
+  template <typename Arg1, typename RetType>
+  FunData1<Arg1,RetType>::FunData1 (FunPtr fun_ptr,
+                                   Arg1   arg1) :
+                 FunDataBase (&FunData1<Arg1,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 arg1 (arg1)
+  {};
+
+
+
+  template <typename Arg1, typename RetType>
+  FunData1<Arg1,RetType>::FunData1 (const FunData1 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 arg1 (fun_data.arg1)
+  {};
+
+
+
+  template <typename Arg1, typename RetType>
+  FunDataBase *
+  FunData1<Arg1,RetType>::clone () const 
+  {
+    return new FunData1 (*this);
+  };
+
+
+
+  template <typename Arg1, typename RetType>
+  void *
+  FunData1<Arg1,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef FunData1<Arg1,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Arg1              arg1    = fun_data->arg1;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (*fun_ptr)(arg1);
+  
+    return 0;
+  };
+
+
+
+  template <typename Arg1, typename RetType>
+  FunData1<Arg1,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+       
+
+  template <typename Arg1, typename RetType>
+  FunEncapsulation
+  FunData1<Arg1,RetType>::ArgCollector::collect_args (Arg1 arg1)
+  {
+    return new FunData1<Arg1,void>(fun_ptr, arg1);
+  };
+  
+
+
+/* ---------------------- FunData2 implementation ------------------------ */
+
+  template <typename Arg1, typename Arg2, typename RetType>
+  FunData2<Arg1,Arg2,RetType>::FunData2 (FunPtr fun_ptr,
+                                        Arg1   arg1,
+                                        Arg2   arg2) :
+                 FunDataBase (&FunData2<Arg1,Arg2,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 arg1 (arg1),
+                 arg2 (arg2)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename RetType>
+  FunData2<Arg1,Arg2,RetType>::FunData2 (const FunData2 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 arg1 (fun_data.arg1),
+                 arg2 (fun_data.arg2)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename RetType>
+  FunDataBase *
+  FunData2<Arg1,Arg2,RetType>::clone () const 
+  {
+    return new FunData2 (*this);
+  };
+
+
+
+  template <typename Arg1, typename Arg2, typename RetType>
+  void *
+  FunData2<Arg1,Arg2,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef FunData2<Arg1,Arg2,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Arg1              arg1    = fun_data->arg1;
+    Arg2              arg2    = fun_data->arg2;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (*fun_ptr)(arg1, arg2);
+  
+    return 0;
+  };
+
+
+
+  template <typename Arg1, typename Arg2, typename RetType>
+  FunData2<Arg1,Arg2,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+       
+
+  
+  template <typename Arg1, typename Arg2, typename RetType>
+  FunEncapsulation
+  FunData2<Arg1,Arg2,RetType>::ArgCollector::collect_args (Arg1 arg1,
+                                                          Arg2 arg2)
+  {
+    return new FunData2<Arg1,Arg2,void>(fun_ptr, arg1, arg2);
+  };
+  
+
+
+/* ---------------------- FunData3 implementation ------------------------ */
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  FunData3<Arg1,Arg2,Arg3,RetType>::FunData3 (FunPtr fun_ptr,
+                                             Arg1   arg1,
+                                             Arg2   arg2,
+                                             Arg3   arg3) :
+                 FunDataBase (&FunData3<Arg1,Arg2,Arg3,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 arg1 (arg1),
+                 arg2 (arg2),
+                 arg3 (arg3)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  FunData3<Arg1,Arg2,Arg3,RetType>::FunData3 (const FunData3 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 arg1 (fun_data.arg1),
+                 arg2 (fun_data.arg2),
+                 arg3 (fun_data.arg3)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  FunDataBase *
+  FunData3<Arg1,Arg2,Arg3,RetType>::clone () const 
+  {
+    return new FunData3 (*this);
+  };
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  void *
+  FunData3<Arg1,Arg2,Arg3,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef FunData3<Arg1,Arg2,Arg3,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Arg1              arg1    = fun_data->arg1;
+    Arg2              arg2    = fun_data->arg2;
+    Arg3              arg3    = fun_data->arg3;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (*fun_ptr)(arg1, arg2, arg3);
+  
+    return 0;
+  };
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  FunData3<Arg1,Arg2,Arg3,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+       
+
+  
+  template <typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  FunEncapsulation
+  FunData3<Arg1,Arg2,Arg3,RetType>::ArgCollector::collect_args (Arg1 arg1,
+                                                               Arg2 arg2,
+                                                               Arg3 arg3)
+  {
+    return new FunData3<Arg1,Arg2,Arg3,void>(fun_ptr, arg1, arg2, arg3);
+  };
+  
+
+
+/* ---------------------- FunData4 implementation ------------------------ */
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::FunData4 (FunPtr fun_ptr,
+                                                  Arg1   arg1,
+                                                  Arg2   arg2,
+                                                  Arg3   arg3,
+                                                  Arg4   arg4) :
+                 FunDataBase (&FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 arg1 (arg1),
+                 arg2 (arg2),
+                 arg3 (arg3),
+                 arg4 (arg4)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::FunData4 (const FunData4 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 arg1 (fun_data.arg1),
+                 arg2 (fun_data.arg2),
+                 arg3 (fun_data.arg3),
+                 arg4 (fun_data.arg4)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  FunDataBase *
+  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::clone () const 
+  {
+    return new FunData4 (*this);
+  };
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  void *
+  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef FunData4<Arg1,Arg2,Arg3,Arg4,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Arg1              arg1    = fun_data->arg1;
+    Arg2              arg2    = fun_data->arg2;
+    Arg3              arg3    = fun_data->arg3;
+    Arg4              arg4    = fun_data->arg4;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (*fun_ptr)(arg1, arg2, arg3, arg4);
+  
+    return 0;
+  };
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  FunEncapsulation
+  FunData4<Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::collect_args (Arg1 arg1,
+                                                                    Arg2 arg2,
+                                                                    Arg3 arg3,
+                                                                    Arg4 arg4)
+  {
+    return new FunData4<Arg1,Arg2,Arg3,Arg4,void>(fun_ptr, arg1, arg2, arg3, arg4);
+  };
+  
+
+
+/* ---------------------- FunData5 implementation ------------------------ */
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::FunData5 (FunPtr fun_ptr,
+                                                       Arg1   arg1,
+                                                       Arg2   arg2,
+                                                       Arg3   arg3,
+                                                       Arg4   arg4,
+                                                       Arg5   arg5) :
+                 FunDataBase (&FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 arg1 (arg1),
+                 arg2 (arg2),
+                 arg3 (arg3),
+                 arg4 (arg4),
+                 arg5 (arg5)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::FunData5 (const FunData5 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 arg1 (fun_data.arg1),
+                 arg2 (fun_data.arg2),
+                 arg3 (fun_data.arg3),
+                 arg4 (fun_data.arg4),
+                 arg5 (fun_data.arg5)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  FunDataBase *
+  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::clone () const 
+  {
+    return new FunData5 (*this);
+  };
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  void *
+  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Arg1              arg1    = fun_data->arg1;
+    Arg2              arg2    = fun_data->arg2;
+    Arg3              arg3    = fun_data->arg3;
+    Arg4              arg4    = fun_data->arg4;
+    Arg5              arg5    = fun_data->arg5;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (*fun_ptr)(arg1, arg2, arg3, arg4, arg5);
+  
+    return 0;
+  };
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+
+
+
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  FunEncapsulation
+  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::collect_args (Arg1 arg1,
+                                                                         Arg2 arg2,
+                                                                         Arg3 arg3,
+                                                                         Arg4 arg4,
+                                                                         Arg5 arg5)
+  {
+    return new FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,void>(fun_ptr, arg1, arg2,
+                                                      arg3, arg4, arg5);
+  };
+  
+
+
+
+/* ---------------------- MemFunData0 implementation ------------------------ */
+
+  template <class Class, typename RetType>
+  MemFunData0<Class,RetType>::MemFunData0 (FunPtr  fun_ptr,
+                                          Class  *object) :
+                 FunDataBase (&MemFunData0<Class,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 object (object)
+  {};
+
+
+
+  template <class Class, typename RetType>
+  MemFunData0<Class,RetType>::MemFunData0 (const MemFunData0 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 object (fun_data.object)
+  {};
+
+
+
+  template <class Class, typename RetType>
+  FunDataBase *
+  MemFunData0<Class,RetType>::clone () const 
+  {
+    return new MemFunData0 (*this);
+  };
+
+
+
+  template <class Class, typename RetType>
+  void *
+  MemFunData0<Class,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef MemFunData0<Class,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Class            *object  = fun_data->object;
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (object->*fun_ptr)();
+  
+    return 0;
+  };
+
+
+
+  template <class Class, typename RetType>
+  MemFunData0<Class,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+       
+
+  
+  template <class Class, typename RetType>
+  FunEncapsulation
+  MemFunData0<Class,RetType>::ArgCollector::collect_args (Class *object)
+  {
+    return new MemFunData0<Class,void>(fun_ptr, object);
+  };
+
+
+/* ---------------------- MemFunData1 implementation ------------------------ */
+
+  template <class Class, typename Arg1, typename RetType>
+  MemFunData1<Class,Arg1,RetType>::MemFunData1 (FunPtr  fun_ptr,
+                                               Class  *object,
+                                               Arg1    arg1) :
+                 FunDataBase (&MemFunData1<Class,Arg1,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 object (object),
+                 arg1 (arg1)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename RetType>
+  MemFunData1<Class,Arg1,RetType>::MemFunData1 (const MemFunData1 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 object (fun_data.object),
+                 arg1 (fun_data.arg1)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename RetType>
+  FunDataBase *
+  MemFunData1<Class,Arg1,RetType>::clone () const 
+  {
+    return new MemFunData1 (*this);
+  };
+
+
+
+  template <class Class, typename Arg1, typename RetType>
+  void *
+  MemFunData1<Class,Arg1,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef MemFunData1<Class,Arg1,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Class            *object  = fun_data->object;
+    Arg1              arg1    = fun_data->arg1;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (object->*fun_ptr)(arg1);
+  
+    return 0;
+  };
+
+
+
+  template <class Class, typename Arg1, typename RetType>
+  MemFunData1<Class,Arg1,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+       
+
+  template <class Class, typename Arg1, typename RetType>
+  FunEncapsulation
+  MemFunData1<Class,Arg1,RetType>::ArgCollector::collect_args (Class *object,
+                                                              Arg1   arg1)
+  {
+    return new MemFunData1<Class,Arg1,void>(fun_ptr, object, arg1);
+  };
+  
+
+
+/* ---------------------- MemFunData2 implementation ------------------------ */
+
+  template <class Class, typename Arg1, typename Arg2, typename RetType>
+  MemFunData2<Class,Arg1,Arg2,RetType>::MemFunData2 (FunPtr  fun_ptr,
+                                                    Class  *object,
+                                                    Arg1    arg1,
+                                                    Arg2    arg2) :
+                 FunDataBase (&MemFunData2<Class,Arg1,Arg2,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 object (object),
+                 arg1 (arg1),
+                 arg2 (arg2)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename RetType>
+  MemFunData2<Class,Arg1,Arg2,RetType>::MemFunData2 (const MemFunData2 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 object (fun_data.object),
+                 arg1 (fun_data.arg1),
+                 arg2 (fun_data.arg2)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename RetType>
+  FunDataBase *
+  MemFunData2<Class,Arg1,Arg2,RetType>::clone () const 
+  {
+    return new MemFunData2 (*this);
+  };
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename RetType>
+  void *
+  MemFunData2<Class,Arg1,Arg2,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef MemFunData2<Class,Arg1,Arg2,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Class            *object  = fun_data->object;
+    Arg1              arg1    = fun_data->arg1;
+    Arg2              arg2    = fun_data->arg2;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (object->*fun_ptr)(arg1, arg2);
+  
+    return 0;
+  };
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename RetType>
+  MemFunData2<Class,Arg1,Arg2,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+       
+
+  
+  template <class Class, typename Arg1, typename Arg2, typename RetType>
+  FunEncapsulation
+  MemFunData2<Class,Arg1,Arg2,RetType>::ArgCollector::collect_args (Class *object,
+                                                                   Arg1   arg1,
+                                                                   Arg2   arg2)
+  {
+    return new MemFunData2<Class,Arg1,Arg2,void>(fun_ptr, object, arg1, arg2);
+  };
+  
+
+
+/* ---------------------- MemFunData3 implementation ------------------------ */
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::MemFunData3 (FunPtr  fun_ptr,
+                                                         Class  *object,
+                                                         Arg1    arg1,
+                                                         Arg2    arg2,
+                                                         Arg3    arg3) :
+                 FunDataBase (&MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 object (object),
+                 arg1 (arg1),
+                 arg2 (arg2),
+                 arg3 (arg3)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::MemFunData3 (const MemFunData3 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 object (fun_data.object),
+                 arg1 (fun_data.arg1),
+                 arg2 (fun_data.arg2),
+                 arg3 (fun_data.arg3)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  FunDataBase *
+  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::clone () const 
+  {
+    return new MemFunData3 (*this);
+  };
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  void *
+  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef MemFunData3<Class,Arg1,Arg2,Arg3,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Class            *object  = fun_data->object;
+    Arg1              arg1    = fun_data->arg1;
+    Arg2              arg2    = fun_data->arg2;
+    Arg3              arg3    = fun_data->arg3;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (object->*fun_ptr)(arg1, arg2, arg3);
+  
+    return 0;
+  };
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+       
+
+  
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename RetType>
+  FunEncapsulation
+  MemFunData3<Class,Arg1,Arg2,Arg3,RetType>::ArgCollector::collect_args (Class *object,
+                                                                        Arg1   arg1,
+                                                                        Arg2   arg2,
+                                                                        Arg3   arg3)
+  {
+    return new MemFunData3<Class,Arg1,Arg2,Arg3,void>(fun_ptr, object,
+                                                     arg1, arg2, arg3);
+  };
+  
+
+
+/* ---------------------- MemFunData4 implementation ------------------------ */
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::MemFunData4 (FunPtr  fun_ptr,
+                                                              Class  *object,
+                                                              Arg1    arg1,
+                                                              Arg2    arg2,
+                                                              Arg3    arg3,
+                                                              Arg4    arg4) :
+                 FunDataBase (&MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 object (object),
+                 arg1 (arg1),
+                 arg2 (arg2),
+                 arg3 (arg3),
+                 arg4 (arg4)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::MemFunData4 (const MemFunData4 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 object (fun_data.object),
+                 arg1 (fun_data.arg1),
+                 arg2 (fun_data.arg2),
+                 arg3 (fun_data.arg3),
+                 arg4 (fun_data.arg4)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  FunDataBase *
+  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::clone () const 
+  {
+    return new MemFunData4 (*this);
+  };
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  void *
+  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Class            *object  = fun_data->object;
+    Arg1              arg1    = fun_data->arg1;
+    Arg2              arg2    = fun_data->arg2;
+    Arg3              arg3    = fun_data->arg3;
+    Arg4              arg4    = fun_data->arg4;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (object->*fun_ptr)(arg1, arg2, arg3, arg4);
+  
+    return 0;
+  };
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename RetType>
+  FunEncapsulation
+  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,RetType>::ArgCollector::collect_args (Class *object,
+                                                                             Arg1   arg1,
+                                                                             Arg2   arg2,
+                                                                             Arg3   arg3,
+                                                                             Arg4   arg4)
+  {
+    return new MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,void>(fun_ptr, object,
+                                                          arg1, arg2, arg3, arg4);
+  };
+  
+
+
+/* ---------------------- MemFunData5 implementation ------------------------ */
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::MemFunData5 (FunPtr  fun_ptr,
+                                                                   Class  *object,
+                                                                   Arg1    arg1,
+                                                                   Arg2    arg2,
+                                                                   Arg3    arg3,
+                                                                   Arg4    arg4,
+                                                                   Arg5    arg5) :
+                 FunDataBase (&MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::thread_entry_point),
+                 fun_ptr (fun_ptr),
+                 object (object),
+                 arg1 (arg1),
+                 arg2 (arg2),
+                 arg3 (arg3),
+                 arg4 (arg4),
+                 arg5 (arg5)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::MemFunData5 (const MemFunData5 &fun_data) :
+                 FunDataBase (fun_data),
+                 fun_ptr (fun_data.fun_ptr),
+                 object (fun_data.object),
+                 arg1 (fun_data.arg1),
+                 arg2 (fun_data.arg2),
+                 arg3 (fun_data.arg3),
+                 arg4 (fun_data.arg4),
+                 arg5 (fun_data.arg5)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  FunDataBase *
+  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::clone () const 
+  {
+    return new MemFunData5 (*this);
+  };
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  void *
+  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::thread_entry_point (void *arg) 
+  {
+                                    // convenience typedef, since we
+                                    // will need that class name
+                                    // several times below
+    typedef MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType> ThisClass;
+  
+    FunEncapsulation *fun_encapsulation
+      = reinterpret_cast<FunEncapsulation*>(arg);
+    const ThisClass *fun_data
+      = dynamic_cast<const ThisClass*> (fun_encapsulation->fun_data_base);
+
+                                  // copy the parameters
+    ThisClass::FunPtr fun_ptr = fun_data->fun_ptr;
+    Class            *object  = fun_data->object;
+    Arg1              arg1    = fun_data->arg1;
+    Arg2              arg2    = fun_data->arg2;
+    Arg3              arg3    = fun_data->arg3;
+    Arg4              arg4    = fun_data->arg4;
+    Arg5              arg5    = fun_data->arg5;
+
+
+                                  // copying of parameters is done,
+                                  // now we can release the lock on
+                                  // #fun_data#
+    fun_data->lock.release ();
+
+                                    // call the function
+    (object->*fun_ptr)(arg1, arg2, arg3, arg4, arg5);
+  
+    return 0;
+  };
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::ArgCollector (FunPtr fun_ptr) :
+                 fun_ptr (fun_ptr)
+  {};
+
+
+
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5, typename RetType>
+  FunEncapsulation
+  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,RetType>::ArgCollector::collect_args (Class *object,
+                                                                                  Arg1   arg1,
+                                                                                  Arg2   arg2,
+                                                                                  Arg3   arg3,
+                                                                                  Arg4   arg4,
+                                                                                  Arg5   arg5)
+  {
+    return new MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,void>(fun_ptr, object,
+                                                               arg1, arg2, arg3, arg4, arg5);
+  };
+  
+
+
+/* ---------------------------------------------------------------- */
+
+  inline
+  FunData0<void>::ArgCollector
+  encapsulate (void (*fun_ptr)())
+  {
+    return fun_ptr;
+  };
+
+
+
+  template <typename Arg1>
+  FunData1<Arg1,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1))
+  {
+    return fun_ptr;
+  };
+  
+
+  
+  template <typename Arg1, typename Arg2>
+  FunData2<Arg1,Arg2,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1, Arg2))
+  {
+    return fun_ptr;
+  };
+  
+
+  
+  template <typename Arg1, typename Arg2, typename Arg3>
+  FunData3<Arg1,Arg2,Arg3,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3))
+  {
+    return fun_ptr;
+  };
+  
+
+  
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  FunData4<Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4))
+  {
+    return fun_ptr;
+  };
+  
+  
+  template <typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+  FunData5<Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
+  encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5))
+  {
+    return fun_ptr;
+  };
+  
+  
+  template <class Class>
+  MemFunData0<Class,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)())
+  {
+    return fun_ptr;
+  };
+
+
+
+  template <class Class, typename Arg1>
+  MemFunData1<Class,Arg1,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1))
+  {
+    return fun_ptr;
+  };
+  
+
+  
+  template <class Class, typename Arg1, typename Arg2>
+  MemFunData2<Class,Arg1,Arg2,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2))
+  {
+    return fun_ptr;
+  };
+  
+
+  
+  template <class Class, typename Arg1, typename Arg2, typename Arg3>
+  MemFunData3<Class,Arg1,Arg2,Arg3,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3))
+  {
+    return fun_ptr;
+  };
+  
+
+  
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
+  MemFunData4<Class,Arg1,Arg2,Arg3,Arg4,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4))
+  {
+    return fun_ptr;
+  };
+
+
+  
+  template <class Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5>
+  MemFunData5<Class,Arg1,Arg2,Arg3,Arg4,Arg5,void>::ArgCollector
+  encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5))
+  {
+    return fun_ptr;
+  };
+
+
+  
+  template <typename ForwardIterator>
+  vector<pair<ForwardIterator,ForwardIterator> >
+  split_range (const ForwardIterator &begin, const ForwardIterator &end,
+              const unsigned int n_intervals)
+  {
+    const unsigned int n_elements              = distance (begin, end);
+    const unsigned int n_elements_per_interval = n_elements / n_intervals;
+    const unsigned int residual                = n_elements % n_intervals;
+    
+    vector<pair<ForwardIterator,ForwardIterator> >
+      return_values (n_intervals);
+
+    return_values[0].first = begin;
+    for (unsigned int i=0; i<n_intervals; ++i)
+      {
+       if (i != n_intervals-1) 
+         {
+           return_values[i].second = return_values[i].first;
+                                            // note: the cast is
+                                            // performed to avoid a
+                                            // warning of gcc that in
+                                            // the library `dist>=0'
+                                            // is checked (dist has a
+                                            // template type, which
+                                            // here is unsigned if no
+                                            // cast is performed)
+           advance (return_values[i].second,
+                    static_cast<signed int>(n_elements_per_interval));
+                                            // distribute residual in
+                                            // division equally among
+                                            // the first few
+                                            // subintervals
+           if (i < residual)
+             ++return_values[i].second;
+           
+           return_values[i+1].first = return_values[i].second;
+         }
+       else
+         return_values[i].second = end;
+      };
+    return return_values;
+  };  
+
+
+           
+};   // end of implementation of namespace Threads
+
+
+#endif // DEAL_II_USE_MT
+
+
+//----------------------------   thread_management.h     ---------------------------
+// end of #ifndef __deal2__thread_management_h
+#endif
+//----------------------------   thread_management.h     ---------------------------
diff --git a/deal.II/base/include/base/thread_manager.h b/deal.II/base/include/base/thread_manager.h
deleted file mode 100644 (file)
index db2523c..0000000
+++ /dev/null
@@ -1,4215 +0,0 @@
-//----------------------------  thread_manager.h  ---------------------------
-//    $Id$
-//    Version: $Name$
-//
-//    Copyright (C) 1998, 1999, 2000 by the deal.II authors
-//
-//    This file is subject to QPL and may not be  distributed
-//    without copyright and license information. Please refer
-//    to the file deal.II/doc/license.html for the  text  and
-//    further information on this license.
-//
-//----------------------------  thread_manager.h  ---------------------------
-#ifndef __deal2__thread_manager_h
-#define __deal2__thread_manager_h
-
-
-#ifdef DEAL_II_USE_MT
-
-#include <ace/Thread_Manager.h>
-
-
-/**
- * This class only wraps up some functionality not included in the
- * #ACE_Thread_Manager# class, namely the possibility to call member
- * functions when spawning threads. Fuethermore, it provides ways to
- * pass arguments to functions taking more than a single parameter.
- *
- * The basic problem with member functions is that they implicitely
- * want to get a pointer to the object they are to work on. Therefore,
- * a member function taking one parameter is in fact a binary
- * function, since the #this# pointer is passed as well. This is
- * reflected by the fact that member function pointers need to be
- * called like this: #object_pointer->(*mem_fun_ptr) (args)#.
- *
- * On the other hand, the thread creation routines (in both the
- * operating system and ACE) only accept unary, global functions as
- * thread entry points. Their argument is a #void*#, which might be
- * used to pass a pointer to a structure to the function; that may
- * then include values of parameters, the address of the member
- * function to be called, and finally the address upon which the
- * function is to operate (i.e. what will be the function's #this#
- * pointer).
- *
- * In practice, this usually leads to code like the following:
- * \begin{verbatim}
- *   class TestClass {
- *            void   spawn_thread ();
- *     static void * thread_entry (void *);
- *            void * threaded_function (int arg1, double arg2);
- *  };
- *
- *  struct ParametersForThreadEntry {
- *    int    arg1;
- *    double arg2;
- *
- *    TestClass * object;
- *  };
- *
- *  void TestClass:spawn_thread () {
- *    ParametersForThreadEntry params;
- *    params.object = this;
- *    params.arg1   = 1;
- *    params.arg2   = 3.1415926;
- *
- *    spawn (..., &thread_entry, (void*)&params, ...);
- *  };
- *
- *  void * TestClass::thread_entry (void * params_tmp) {
- *                        // cast parameters object to the
- *                        // type it really has
- *    ParametersForThreadEntry * params =
- *               (ParametersForThreadEntry*)params_tmp;
- *                        // unpack entries of params
- *                        // and call member function
- *    void * return_value =
- *         (params->object)->threaded_function (params.arg1, params.arg2);
- *    return return_value;
- *  };
- *
- *  void * TestClass::threaded_function (int arg1, double arg2) {
- *    ... // do something in parallel to the main thread
- *  };
- * \end{verbatim}
- *
- * Note that the #static# in the declaration of #thread_entry# means
- * that is not a true member function in that it does not take a
- * #this# pointer and therefore is truely a unary function. However,
- * due to this, it can't access member variables.
- *
- * This program above suffers from several problems:
- * \begin{enumerate}
- *   \item One has to have a different structure for passing arguments
- *     to functions (if there would be another function taking two
- *     integers instead of the argument list above, one would have to have
- *     another parameter structure including two integers).
- *
- *   \item One would also need a different #thread_entry# function for
- *     all functions to be called, since each of them can call only
- *     one member function (one could include the address of the member
- *     function into the structure wrapped around the parameter values;
- *     then one would only need one #thread_entry# function for each
- *     different parameter list of functions).
- *
- * \item The program has a bug: #params# in #spawn_thread# is a local
- *     variable, which is destroyed at the end of the function. If now
- *     the operating system returns after executing the #spawn# call,
- *     but takes some time for internal actions before passing control
- *     to the #thread_entry# function, then the pointer given to
- *     #thread_entry# might not point to anything reasonable any more,
- *     thus producing random results.
- *
- *     The problem gets even worse, if the parameters in
- *     #ParametersForThreadEntry# contain not only values, but also
- *     references of pointers to other data elements; one will then
- *     have to guarantee that not only the #params# variable is
- *     preserved until its values are copied by #thread_entry# to the
- *     places where function parameters of #threaded_function# are
- *     stored (i.e. usually on the stack), but also the lifetime of
- *     the variables to which the elements of #params# point, have to
- *     be long enough to guarantee that they still exist whenever
- *     #threaded_function# uses them.
- * \end{enumerate}
- *
- * The present class at leasts solves the first two problems:
- * \begin{enumerate}
- * \item By providing standardized templated class for parameter
- *     transfer, it is no more necessary to declare parameter
- *     structures one-by-one. For example, #ParametersForThreadEntry#
- *     above could be replaced by
- *     #ThreadManager::Mem_Fun_Data2<TestClass,int,double>#, with
- *     template parameters representing the type of the class for
- *     which a member function shall be called, and the parameters to
- *     this function.
- *
- * \item The #thread_entry# function above was declared as a static
- *     member function in order to not clutter up the global namespace
- *     with thread entry functions for each and every purpose. It
- *     could, however, also be a global function, or a static member
- *     function of another class. This class provides a thread entry
- *     function for each possible list of parameters for a member
- *     function; these thread entry functions obviously are made
- *     #static#, i.e. you need not create an object of class
- *     #ThreadManager# to call them, and they satisfy the requirement
- *     of #spawn# to be of data type (function pointer type) #void *
- *     (*) (void *)#.
- * \end{enumerate}
- *
- * The third problem mentioned above cannot be solved so easily,
- * however. It is still up to the calling function to guarantee that
- * the #params# structure exists long enough and that objects to which
- * elements of #params# point exist long enough. There are at least
- * two strategies for this problem:
- * \begin{enumerate}
- * \item Allocate the parameters object on the stack: one could modify
- *     the example as follows:
- *     \begin{verbatim}
- *       void TestClass:spawn_thread () {
- *         ParametersForThreadEntry *params = new ParametersForThreadEntry;
- *         params->object = this;
- *         params->arg1   = 1;
- *         params->arg2   = 3.1415926;
- *
- *         spawn (..., &thread_entry, (void*)params, ...);
- *       };
- *     \end{verbatim}
- *
- *     Thus, the parameters object is on the heap instead of on the
- *     stack, and its lifetime is until it is #delete#d some
- *     time. Again, the #spawn_thread# function can't do that since it
- *     does not exactly know at which point the second thread does not
- *     need the data any more. However, the #thread_entry# function
- *     could do that:
- *     \begin{verbatim}
- *       void * TestClass::thread_entry (void * params_tmp) {
- *                             // cast parameters object to the
- *                             // type it really has
- *         ParametersForThreadEntry * params =
- *                    (ParametersForThreadEntry*)params_tmp;
- *                             // unpack entries of params
- *                             // and call member function
- *         void * return_value =
- *              (params->object)->threaded_function (params.arg1, params.arg2);
- *
- *                             // delete parameters object
- *         delete params;
- * 
- *         return return_value;
- *       };
- *     \end{verbatim}
- *     This is safe, since the parameters object is deleted only after
- *     the member function #threaded_function# returns; the parameters
- *     are therefore no more needed.
- *
- *     The downside here is that there is another system function
- *     which is commonly called: #spawn_n#, which creates #n# threads
- *     at the same time, i.e. it jumps into #thread_entry# #n# times
- *     at once. However, the #delete# operation must only be performed
- *     once, namely by the thread which exits last; the code in
- *     #thread_entry# would therefore have to synchronize which thread
- *     calls the #delete# and when. This is feasible, but difficult.
- *
- * \item Blocking the first thread after spawning other threads: this would
- *     yield an implementation of #spawn_thread# like this:
- *     \begin{verbatim}
- *       void TestClass:spawn_thread () {
- *         ParametersForThreadEntry params;
- *         params.object = this;
- *         params.arg1   = 1;
- *         params.arg2   = 3.1415926;
- *
- *         spawn (..., &thread_entry, (void*)&params, ...);
- *
- *         ... // some code which waits until the spawned thread returns
- *       };
- *     \end{verbatim}
- *     Since execution of #spawn_treads# is suspended until the spawned
- *     thread exits, so is the destruction of the #params# object. It is
- *     therefore guaranteed that it exists longer than the lifetime of the
- *     thread which might use it.
- *
- *     Obviously, the above function is useless as stated here, since
- *     if we start a new threads and then stop the old one until the
- *     new one returns, we could as well have called the member
- *     function directly, without need to create a new thread. This
- *     approach therefore is only useful, if the function creates more
- *     than one thread and waits for them all to return. Thread
- *     creation may happen using several #spawn# calls (and maybe
- *     different parameter objects), as well as using the #spawn_n#
- *     function. Destruction of the parameter object remains with the
- *     calling function, as in the original example.
- * \end{enumerate}
- *
- *
- * \subsection{Example of use of this class}
- *
- * The following example shows how to use the elements of this class.
- * \begin{verbatim}
- *  void TestClass:spawn_thread () {
- *                     // create ThreadManager object
- *    ThreadManager thread_manager;
- *                     // generate an object to pass
- *                     // the two parameters
- *    const ThreadManager::Mem_Fun_Data2<const SparseMatrix<number>,
- *                                      unsigned int,
- *                                      unsigned int> 
- *         mem_fun_data (this,     // object to operate on
- *                        1,        // first parameter
- *                        2,        // second parameter
- *                                  // address of member function
- *                       &TestClass::threaded_function 
- *                       );
- *
- *                     // spawn a thread
- *     thread_manager.spawn (&mem_fun_data);
- *
- *     ...             // do something more, start more threads, etc
- *
- *
- *                    // ... and wait until they're finished:
- *     thread_manager.wait ();
- *  };
- * \end{verbatim}
- *
- * Note that in this example, there is no need for the #thread_entry#
- * function and the structure encapsulating parameters. Often,
- * functions will not have a return value, i.e. their return type is
- * #void#. In this case, the interface above would force us to declare
- * them as returning a #void*# anyway. Therefore, this class also
- * allows for functions without a return type; a Null pointer will
- * then be returned to the caller.
- *
- * Usage is exactly as above, but that the #threaded_function# may
- * also be a #void# function. This is done by a second constructor of
- * the #Mem_Fun_Data# structures, where either a pointer to a #void#
- * function or a pointer to a #void*# function is set. The other
- * pointer is always set to zero. If the function returns no value,
- * then the #thread_entry# function of this class returns a Null
- * pointer instead.
- *
- *
- * \subsection{Using this class on global functions}
- *
- * The structures provided by this class are easier to use than the
- * methods of the basic ThreadManager. It is also possible to call global
- * functions (without a this pointer) as a thread. The struct used to
- * package all data needed to call a global functions is called #Fun_Data#. 
- *
- * The following example shows how to call a global function
- * \begin{verbatim}
- *  void TestClass::spawn_thread () {
- *                     // create ThreadManager object
- *    ThreadManager thread_manager;
- *                     // generate an object to pass
- *                     // the two parameters
- *    const ThreadManager::Fun_Data2<unsigned int,
- *                                  unsigned int> 
- *         fun_data ( 1,        // first parameter
- *                     2,        // second parameter
- *                               // address of global function
- *                    &threaded_function 
- *                   );
- *
- *                     // spawn a thread
- *     thread_manager.spawn (&fun_data);
- *
- *     ...             // do something more, start more threads, etc
- *
- *
- *                    // ... and wait until they're finished:
- *     thread_manager.wait ();
- *  };
- * \end{verbatim}
- * @author Wolfgang Bangerth, 1999, 2000. Extensions by Thomas Richter, 2000
- */
-class ThreadManager : public ACE_Thread_Manager 
-{
-  public:
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific void member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class>
-    struct Mem_Fun_Data0
-    {
-       typedef void * (Class::*MemFun) ();
-
-       typedef void (Class::*VoidMemFun) ();
-
-       Class     *object;
-       MemFun     mem_fun;
-       VoidMemFun void_mem_fun;
-
-       Mem_Fun_Data0 (Class *object,
-                      MemFun mem_fun) :
-                       object (object),
-                       mem_fun (mem_fun),
-                       void_mem_fun (0) {};
-
-       Mem_Fun_Data0 (Class     *object,
-                      VoidMemFun void_mem_fun) :
-                       object (object),
-                       mem_fun (0),
-                       void_mem_fun (void_mem_fun) {};
-    };
-
-
-                                    /**
-                                     * This class is used to package all
-                                     * data needed to call a specific unary
-                                     * member function of an object. It is
-                                     * used to pass it over to a static
-                                     * function which serves as the entry
-                                     * points for a new thread; that function
-                                     * in turn calls the member function
-                                     * with its object and argument.
-                                     *
-                                     * By the way, the strange naming
-                                     * of this class with capital
-                                     * latters and underscores tries
-                                     * to mimic the corresponding
-                                     * classes of the STL for
-                                     * non-member functions.
-                                     */
-    template <typename Class, typename Arg>
-    struct Mem_Fun_Data1
-    {
-                                        /**
-                                         * Convenience #typedef# for
-                                         * the member functions data
-                                         * type. This is for member
-                                         * functions that return a
-                                         * #void *#, which is
-                                         * returned to the caller.
-                                         */
-       typedef void * (Class::*MemFun) (Arg);
-
-                                        /**
-                                         * Convenience #typedef# for
-                                         * the member functions data
-                                         * type. This is for member
-                                         * functions without return
-                                         * value. A #(void*)0# is
-                                         * then returned to the
-                                         * caller.
-                                         */
-       typedef void (Class::*VoidMemFun) (Arg);
-       
-                                        /**
-                                         * Pointer to the object for which
-                                         * the member function is to be
-                                         * called.
-                                         */
-       Class *object;
-
-                                        /**
-                                         * Argument for the function call.
-                                         */
-       Arg    arg;
-       
-                                        /**
-                                         * Pointer to the member
-                                         * function if that returns a
-                                         * #void*#. If the function
-                                         * has no return value, then
-                                         * this pointer is zero.
-                                         */
-       MemFun     mem_fun;
-
-                                        /**
-                                         * If the function has no
-                                         * return value, then this
-                                         * pointer is used. If the
-                                         * function has a return
-                                         * value, then this pointer
-                                         * is zero.
-                                         */
-       VoidMemFun void_mem_fun;
-
-                                        /**
-                                         * Constructor for functions
-                                         * with a return value.
-                                         */
-       Mem_Fun_Data1 (Class *object,
-                      Arg    arg,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg (arg),
-                       mem_fun (mem_fun),
-                       void_mem_fun (0) {};
-
-                                        /**
-                                         * Constructor for functions
-                                         * without a return value.
-                                         */
-       Mem_Fun_Data1 (Class *object,
-                      Arg    arg,
-                      VoidMemFun void_mem_fun) :
-                       object (object),
-                       arg (arg),
-                       mem_fun (0),
-                       void_mem_fun (void_mem_fun) {};
-    };
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific binary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2>
-    struct Mem_Fun_Data2
-    {
-       typedef void * (Class::*MemFun) (Arg1, Arg2);
-
-       typedef void (Class::*VoidMemFun) (Arg1, Arg2);
-
-       Class     *object;
-       Arg1       arg1;
-       Arg2       arg2;
-
-       MemFun     mem_fun;
-       VoidMemFun void_mem_fun;
-
-       Mem_Fun_Data2 (Class *object,
-                      Arg1   arg1,
-                      Arg2   arg2,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       mem_fun (mem_fun),
-                       void_mem_fun (0) {};
-
-       Mem_Fun_Data2 (Class     *object,
-                      Arg1       arg1,
-                      Arg2       arg2,
-                      VoidMemFun void_mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       mem_fun (0),
-                       void_mem_fun (void_mem_fun) {};
-    };
-
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific ternary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2, typename Arg3>
-    struct Mem_Fun_Data3
-    {
-       typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3);
-       typedef void   (Class::*VoidMemFun) (Arg1, Arg2, Arg3);
-
-       Class     *object;
-       Arg1       arg1;
-       Arg2       arg2;
-       Arg3       arg3;
-       MemFun     mem_fun;
-       VoidMemFun void_mem_fun;
-
-       Mem_Fun_Data3 (Class *object,
-                      Arg1   arg1,
-                      Arg2   arg2,
-                      Arg3   arg3,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       arg3 (arg3),
-                       mem_fun (mem_fun),
-                       void_mem_fun (0) {};
-
-       Mem_Fun_Data3 (Class     *object,
-                      Arg1       arg1,
-                      Arg2       arg2,
-                      Arg3       arg3,
-                      VoidMemFun void_mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       arg3 (arg3),
-                       mem_fun (0),
-                       void_mem_fun (void_mem_fun) {};
-    };
-
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific quaternary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class,
-              typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4>
-    struct Mem_Fun_Data4
-    {
-       typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4);
-       typedef void   (Class::*VoidMemFun) (Arg1, Arg2, Arg3, Arg4);
-       
-       Class     *object;
-       Arg1       arg1;
-       Arg2       arg2;
-       Arg3       arg3;
-       Arg4       arg4;
-       MemFun     mem_fun;
-       VoidMemFun void_mem_fun;
-
-       Mem_Fun_Data4 (Class *object,
-                      Arg1   arg1,
-                      Arg2   arg2,
-                      Arg3   arg3,
-                      Arg4   arg4,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       arg3 (arg3),
-                       arg4 (arg4),
-                       mem_fun (mem_fun),
-                       void_mem_fun (0) {};
-       
-       Mem_Fun_Data4 (Class     *object,
-                      Arg1       arg1,
-                      Arg2       arg2,
-                      Arg3       arg3,
-                      Arg4       arg4,
-                      VoidMemFun void_mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       arg3 (arg3),
-                       arg4 (arg4),
-                       mem_fun (0),
-                       void_mem_fun (void_mem_fun) {};
-    };
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific quintary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class,
-              typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5>
-    struct Mem_Fun_Data5
-    {
-       typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4, Arg5);
-       typedef void   (Class::*VoidMemFun) (Arg1, Arg2, Arg3, Arg4, Arg5);
-       Class     *object;
-       Arg1       arg1;
-       Arg2       arg2;
-       Arg3       arg3;
-       Arg4       arg4;
-       Arg5       arg5;
-       MemFun     mem_fun;
-       VoidMemFun void_mem_fun;
-
-       Mem_Fun_Data5 (Class *object,
-                      Arg1   arg1,
-                      Arg2   arg2,
-                      Arg3   arg3,
-                      Arg4   arg4,
-                      Arg5   arg5,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       arg3 (arg3),
-                       arg4 (arg4),
-                       arg5 (arg5),
-                       mem_fun (mem_fun),
-                       void_mem_fun (0) {};
-
-       Mem_Fun_Data5 (Class     *object,
-                      Arg1       arg1,
-                      Arg2       arg2,
-                      Arg3       arg3,
-                      Arg4       arg4,
-                      Arg5       arg5,
-                      VoidMemFun void_mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       arg3 (arg3),
-                       arg4 (arg4),
-                       arg5 (arg5),
-                       mem_fun (0),
-                       void_mem_fun (void_mem_fun) {};
-    };
-
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific hexary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class,
-              typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6>
-    struct Mem_Fun_Data6
-    {
-       typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
-       typedef void   (Class::*VoidMemFun) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6);
-
-       Class     *object;
-       Arg1       arg1;
-       Arg2       arg2;
-       Arg3       arg3;
-       Arg4       arg4;
-       Arg5       arg5;
-       Arg6       arg6;
-       MemFun     mem_fun;
-       VoidMemFun void_mem_fun;
-
-       Mem_Fun_Data6 (Class *object,
-                      Arg1   arg1,
-                      Arg2   arg2,
-                      Arg3   arg3,
-                      Arg4   arg4,
-                      Arg5   arg5,
-                      Arg6   arg6,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       arg3 (arg3),
-                       arg4 (arg4),
-                       arg5 (arg5),
-                       arg6 (arg6),
-                       mem_fun (mem_fun),
-                       void_mem_fun (0) {};
-
-       Mem_Fun_Data6 (Class     *object,
-                      Arg1       arg1,
-                      Arg2       arg2,
-                      Arg3       arg3,
-                      Arg4       arg4,
-                      Arg5       arg5,
-                      Arg6       arg6,
-                      VoidMemFun void_mem_fun) :
-                       object (object),
-                       arg1 (arg1),
-                       arg2 (arg2),
-                       arg3 (arg3),
-                       arg4 (arg4),
-                       arg5 (arg5),
-                       arg6 (arg6),
-                       mem_fun (0),
-                       void_mem_fun (void_mem_fun) {};
-    };
-    
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific heptary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class,
-              typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6,
-              typename Arg7>
-      struct Mem_Fun_Data7
-      {
-       typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4, Arg5,
-                                        Arg6, Arg7);
-       Class *object;
-       Arg1   arg1;
-       Arg2   arg2;
-       Arg3   arg3;
-       Arg4   arg4;
-       Arg5   arg5;
-       Arg6   arg6;
-       Arg7   arg7;
-       MemFun mem_fun;
-
-       Mem_Fun_Data7 (Class *object,
-                      Arg1   arg1,
-                      Arg2   arg2,
-                      Arg3   arg3,
-                      Arg4   arg4,
-                      Arg5   arg5,
-                      Arg6   arg6,
-                      Arg7   arg7,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg1  (arg1),
-                       arg2  (arg2),
-                       arg3  (arg3),
-                       arg4  (arg4),
-                       arg5  (arg5),
-                       arg6  (arg6),
-                        arg7  (arg7),
-                       mem_fun (mem_fun) {};
-    };
-    
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific octary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class,
-              typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6,
-              typename Arg7, typename Arg8>
-    struct Mem_Fun_Data8
-    {
-       typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4, Arg5,
-                                        Arg6, Arg7, Arg8);
-       Class *object;
-       Arg1   arg1;
-       Arg2   arg2;
-       Arg3   arg3;
-       Arg4   arg4;
-       Arg5   arg5;
-       Arg6   arg6;
-       Arg7   arg7;
-       Arg8   arg8;
-       MemFun mem_fun;
-
-       Mem_Fun_Data8 (Class *object,
-                      Arg1   arg1,
-                      Arg2   arg2,
-                      Arg3   arg3,
-                      Arg4   arg4,
-                      Arg5   arg5,
-                      Arg6   arg6,
-                      Arg7   arg7,
-                      Arg8   arg8,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg1  (arg1),
-                       arg2  (arg2),
-                       arg3  (arg3),
-                       arg4  (arg4),
-                       arg5  (arg5),
-                       arg6  (arg6),
-                        arg7  (arg7),
-                       arg8  (arg8),
-                        mem_fun (mem_fun) {};
-    };
-
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific nonary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class,
-              typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6,
-              typename Arg7, typename Arg8,
-              typename Arg9>
-    struct Mem_Fun_Data9
-    {
-       typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4, Arg5,
-                                        Arg6, Arg7, Arg8, Arg9);
-       Class *object;
-       Arg1   arg1;
-       Arg2   arg2;
-       Arg3   arg3;
-       Arg4   arg4;
-       Arg5   arg5;
-       Arg6   arg6;
-       Arg7   arg7;
-       Arg8   arg8;
-       Arg9   arg9;
-       MemFun mem_fun;
-
-       Mem_Fun_Data9 (Class *object,
-                       Arg1   arg1,
-                       Arg2   arg2,
-                       Arg3   arg3,
-                       Arg4   arg4,
-                       Arg5   arg5,
-                       Arg6   arg6,
-                       Arg7   arg7,
-                       Arg8   arg8,
-                       Arg9   arg9,
-                      MemFun mem_fun) :
-                       object (object),
-                       arg1  (arg1),
-                       arg2  (arg2),
-                       arg3  (arg3),
-                       arg4  (arg4),
-                       arg5  (arg5),
-                       arg6  (arg6),
-                        arg7  (arg7),
-                       arg8  (arg8),
-                       arg9  (arg9),
-                       mem_fun (mem_fun) {};
-    };
-
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * specific decary member
-                                     * function of an object. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Class,
-              typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6,
-              typename Arg7, typename Arg8,
-              typename Arg9, typename Arg10>
-    struct Mem_Fun_Data10
-    {
-       typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4, Arg5,
-                                        Arg6, Arg7, Arg8, Arg9, Arg10);
-       Class *object;
-       Arg1   arg1;
-       Arg2   arg2;
-       Arg3   arg3;
-       Arg4   arg4;
-       Arg5   arg5;
-       Arg6   arg6;
-       Arg7   arg7;
-       Arg8   arg8;
-       Arg9   arg9;
-       Arg10  arg10;
-       MemFun mem_fun;
-
-       Mem_Fun_Data10 (Class *object,
-                       Arg1   arg1,
-                       Arg2   arg2,
-                       Arg3   arg3,
-                       Arg4   arg4,
-                       Arg5   arg5,
-                       Arg6   arg6,
-                       Arg7   arg7,
-                       Arg8   arg8,
-                       Arg9   arg9,
-                       Arg10  arg10,
-                       MemFun mem_fun) :
-                       object (object),
-                       arg1  (arg1),
-                       arg2  (arg2),
-                       arg3  (arg3),
-                       arg4  (arg4),
-                       arg5  (arg5),
-                       arg6  (arg6),
-                        arg7  (arg7),
-                       arg8  (arg8),
-                       arg9  (arg9),
-                       arg10 (arg10),
-                       mem_fun (mem_fun) {};
-    };
-
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1>
-      struct Fun_Data1
-      {
-         typedef void * (*FunPtr) (Arg1);
-         typedef void   (*VoidFunPtr) (Arg1);
-         Arg1   arg1;
-         FunPtr fun_ptr;
-         VoidFunPtr void_fun_ptr;
-         
-         Fun_Data1 (Arg1   arg1,
-                    FunPtr fun_ptr) :
-                         arg1  (arg1),
-                         fun_ptr (fun_ptr),
-                         void_fun_ptr (0) {};
-         
-         Fun_Data1 (Arg1   arg1,
-                    VoidFunPtr void_fun_ptr) :
-                         arg1  (arg1),
-                         fun_ptr (0),
-                         void_fun_ptr (void_fun_ptr) {};
-      };
-
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2>
-      struct Fun_Data2
-      {
-         typedef void * (*FunPtr) (Arg1 , Arg2);
-         typedef void   (*VoidFunPtr) (Arg1 , Arg2);
-         Arg1       arg1;
-         Arg2       arg2;
-         FunPtr     fun_ptr;
-         VoidFunPtr void_fun_ptr;
-         
-         Fun_Data2 (Arg1   arg1,
-                    Arg2   arg2,
-                    FunPtr fun_ptr) :
-                         arg1  (arg1),
-                         arg2  (arg2),
-                         fun_ptr (fun_ptr),
-                         void_fun_ptr (0) {};
-
-         Fun_Data2 (Arg1       arg1,
-                    Arg2       arg2,
-                    VoidFunPtr void_fun_ptr) :
-                         arg1  (arg1),
-                         arg2  (arg2),
-                         fun_ptr (0),
-                         void_fun_ptr (void_fun_ptr) {};
-      };
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2,
-              typename Arg3>
-      struct Fun_Data3
-      {
-         typedef void * (*FunPtr) (Arg1 , Arg2, Arg3);
-         typedef void   (*VoidFunPtr) (Arg1 , Arg2, Arg3);
-         Arg1   arg1;
-         Arg2   arg2;
-         Arg3   arg3;
-         FunPtr fun_ptr;
-         VoidFunPtr void_fun_ptr;
-         
-         Fun_Data3 (Arg1   arg1,
-                    Arg2   arg2,
-                    Arg3   arg3,
-                    FunPtr fun_ptr) :
-                         arg1  (arg1),
-                         arg2  (arg2),
-                         arg3  (arg3),
-                         fun_ptr (fun_ptr),
-                         void_fun_ptr (0) {};
-
-         Fun_Data3 (Arg1   arg1,
-                    Arg2   arg2,
-                    Arg3   arg3,
-                    VoidFunPtr void_fun_ptr) :
-                         arg1  (arg1),
-                         arg2  (arg2),
-                         arg3  (arg3),
-                         fun_ptr (0),
-                         void_fun_ptr (void_fun_ptr) {};
-      };
-    
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4>
-      struct Fun_Data4
-      {
-         typedef void * (*FunPtr) (Arg1 , Arg2, Arg3, Arg4);
-         typedef void   (*VoidFunPtr) (Arg1 , Arg2, Arg3, Arg4);
-
-         Arg1       arg1;
-         Arg2       arg2;
-         Arg3       arg3;
-         Arg4       arg4;
-         FunPtr     fun_ptr;
-         VoidFunPtr void_fun_ptr;
-         
-         Fun_Data4 (Arg1   arg1,
-                    Arg2   arg2,
-                    Arg3   arg3,
-                    Arg4   arg4,
-                    FunPtr fun_ptr) :
-                         arg1  (arg1),
-                         arg2  (arg2),
-                         arg3  (arg3),
-                         arg4  (arg4),
-                         fun_ptr (fun_ptr),
-                         void_fun_ptr (0) {};
-         Fun_Data4 (Arg1       arg1,
-                    Arg2       arg2,
-                    Arg3       arg3,
-                    Arg4       arg4,
-                    VoidFunPtr void_fun_ptr) :
-                         arg1  (arg1),
-                         arg2  (arg2),
-                         arg3  (arg3),
-                         arg4  (arg4),
-                         fun_ptr (0),
-                         void_fun_ptr (void_fun_ptr) {};
-      };
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5>
-    struct Fun_Data5
-    {
-       typedef void * (*FunPtr) (Arg1 , Arg2, Arg3, Arg4, Arg5);
-       typedef void   (*VoidFunPtr) (Arg1 , Arg2, Arg3, Arg4, Arg5);
-
-       Arg1       arg1;
-       Arg2       arg2;
-       Arg3       arg3;
-       Arg4       arg4;
-       Arg5       arg5;
-       FunPtr     fun_ptr;
-       VoidFunPtr void_fun_ptr;
-         
-       Fun_Data5 (Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3,
-                  Arg4   arg4,
-                  Arg5   arg5,
-                  FunPtr fun_ptr) :
-                       arg1  (arg1),
-                       arg2  (arg2),
-                       arg3  (arg3),
-                       arg4  (arg4),
-                       arg5  (arg5),
-                       fun_ptr (fun_ptr),
-                       void_fun_ptr (0) {};
-       Fun_Data5 (Arg1       arg1,
-                  Arg2       arg2,
-                  Arg3       arg3,
-                  Arg4       arg4,
-                  Arg5       arg5,
-                  VoidFunPtr void_fun_ptr) :
-                       arg1  (arg1),
-                       arg2  (arg2),
-                       arg3  (arg3),
-                       arg4  (arg4),
-                       arg5  (arg5),
-                       fun_ptr (0),
-                       void_fun_ptr (void_fun_ptr) {};
-    };
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6>
-      struct Fun_Data6
-      {
-         typedef void * (*FunPtr) (Arg1 , Arg2, Arg3, Arg4, Arg5,
-                                   Arg6);
-         Arg1   arg1;
-         Arg2   arg2;
-         Arg3   arg3;
-         Arg4   arg4;
-         Arg5   arg5;
-         Arg6   arg6;
-         FunPtr fun_ptr;
-         
-         Fun_Data6 (Arg1   arg1,
-                    Arg2   arg2,
-                    Arg3   arg3,
-                    Arg4   arg4,
-                    Arg5   arg5,
-                    Arg6   arg6,
-                    FunPtr fun_ptr) :
-                         arg1  (arg1),
-                         arg2  (arg2),
-                         arg3  (arg3),
-                         arg4  (arg4),
-                         arg5  (arg5),
-                         arg6  (arg6),
-                         fun_ptr (fun_ptr) {};
-      };
-
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6,
-              typename Arg7>
-    struct Fun_Data7
-    {
-       typedef void * (*FunPtr) (Arg1 , Arg2, Arg3, Arg4, Arg5,
-                                 Arg6, Arg7);
-       Arg1   arg1;
-       Arg2   arg2;
-       Arg3   arg3;
-       Arg4   arg4;
-       Arg5   arg5;
-       Arg6   arg6;
-       Arg7   arg7;
-       FunPtr fun_ptr;
-         
-       Fun_Data7 (Arg1   arg1,
-                  Arg2   arg2,
-                  Arg3   arg3,
-                  Arg4   arg4,
-                  Arg5   arg5,
-                  Arg6   arg6,
-                  Arg7   arg7,
-                  FunPtr fun_ptr) :
-                       arg1  (arg1),
-                       arg2  (arg2),
-                       arg3  (arg3),
-                       arg4  (arg4),
-                       arg5  (arg5),
-                       arg6  (arg6),
-                       arg7  (arg7),
-                       fun_ptr (fun_ptr) {};
-    };
-    
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6,
-              typename Arg7, typename Arg8>
-      struct Fun_Data8
-      {
-         typedef void * (*FunPtr) (Arg1 , Arg2, Arg3, Arg4, Arg5,
-                                   Arg6, Arg7, Arg8);
-         Arg1   arg1;
-         Arg2   arg2;
-         Arg3   arg3;
-         Arg4   arg4;
-         Arg5   arg5;
-         Arg6   arg6;
-         Arg7   arg7;
-         Arg8   arg8;
-         FunPtr fun_ptr;
-         
-         Fun_Data8 (Arg1   arg1,
-                    Arg2   arg2,
-                    Arg3   arg3,
-                    Arg4   arg4,
-                    Arg5   arg5,
-                    Arg6   arg6,
-                    Arg7   arg7,
-                    Arg8   arg8,
-                    FunPtr fun_ptr) :
-                         arg1  (arg1),
-                         arg2  (arg2),
-                         arg3  (arg3),
-                         arg4  (arg4),
-                         arg5  (arg5),
-                         arg6  (arg6),
-                         arg7  (arg7),
-                         arg8  (arg8),
-                         fun_ptr (fun_ptr) {};
-      };
-    
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * global function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6,
-              typename Arg7, typename Arg8,
-      typename Arg9>
-      struct Fun_Data9
-      {
-         typedef void * (*FunPtr) (Arg1 , Arg2, Arg3, Arg4, Arg5,
-                                   Arg6, Arg7, Arg8, Arg9);
-         Arg1   arg1;
-         Arg2   arg2;
-         Arg3   arg3;
-         Arg4   arg4;
-         Arg5   arg5;
-         Arg6   arg6;
-         Arg7   arg7;
-         Arg8   arg8;
-         Arg9   arg9;
-         FunPtr fun_ptr;
-         
-         Fun_Data9 (Arg1   arg1,
-                     Arg2   arg2,
-                     Arg3   arg3,
-                     Arg4   arg4,
-                     Arg5   arg5,
-                     Arg6   arg6,
-                     Arg7   arg7,
-                     Arg8   arg8,
-                     Arg9   arg9,
-                    FunPtr fun_ptr) :
-                         arg1  (arg1),
-           arg2  (arg2),
-           arg3  (arg3),
-           arg4  (arg4),
-           arg5  (arg5),
-           arg6  (arg6),
-           arg7  (arg7),
-           arg8  (arg8),
-           arg9  (arg9),
-           fun_ptr (fun_ptr) {};
-      };
-                                    
-                                    /**
-                                     * This class is used to package
-                                     * all data needed to call a
-                                     * function. See the
-                                     * general documentation of the
-                                     * #ThreadManager# class or of
-                                     * the class
-                                     * #ThreadManager::Mem_Fun_Data1#
-                                     * for more information.
-                                     */
-    template <typename Arg1, typename Arg2,
-              typename Arg3, typename Arg4,
-              typename Arg5, typename Arg6,
-              typename Arg7, typename Arg8,
-      typename Arg9, typename Arg10>
-      struct Fun_Data10
-      {
-         typedef void * (*FunPtr) (Arg1 , Arg2, Arg3, Arg4, Arg5,
-                                   Arg6, Arg7, Arg8, Arg9, Arg10);
-         Arg1   arg1;
-         Arg2   arg2;
-         Arg3   arg3;
-         Arg4   arg4;
-         Arg5   arg5;
-         Arg6   arg6;
-         Arg7   arg7;
-         Arg8   arg8;
-         Arg9   arg9;
-         Arg10  arg10;
-         FunPtr fun_ptr;
-         
-         Fun_Data10 (Arg1   arg1,
-                     Arg2   arg2,
-                     Arg3   arg3,
-                     Arg4   arg4,
-                     Arg5   arg5,
-                     Arg6   arg6,
-                     Arg7   arg7,
-                     Arg8   arg8,
-                     Arg9   arg9,
-                     Arg10  arg10,
-                     FunPtr fun_ptr) :
-                         arg1  (arg1),
-           arg2  (arg2),
-           arg3  (arg3),
-           arg4  (arg4),
-           arg5  (arg5),
-           arg6  (arg6),
-           arg7  (arg7),
-           arg8  (arg8),
-           arg9  (arg9),
-           arg10 (arg10),
-           fun_ptr (fun_ptr) {};
-      };
-
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking no arguments.
-                                     */
-    template <typename ObjectClass>
-    int spawn (Mem_Fun_Data0<ObjectClass> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking a single argument.
-                                     */
-    template <typename ObjectClass, typename Arg>
-    int spawn (Mem_Fun_Data1<ObjectClass,Arg> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking two arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2>
-    int spawn (Mem_Fun_Data2<ObjectClass,Arg1,Arg2> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking three arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2, typename Arg3>
-    int spawn (Mem_Fun_Data3<ObjectClass,Arg1,Arg2,Arg3> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking four arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-    int spawn (Mem_Fun_Data4<ObjectClass,Arg1,Arg2,Arg3,Arg4> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking five arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5>
-    int spawn (Mem_Fun_Data5<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking six arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6>
-    int spawn (Mem_Fun_Data6<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking seven arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7>
-    int spawn (Mem_Fun_Data7<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                        Arg6,Arg7> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking eight arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7, typename Arg8>
-    int spawn (Mem_Fun_Data8<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                          Arg6,Arg7,Arg8> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking nine arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7, typename Arg8,
-                                    typename Arg9>
-    int spawn (Mem_Fun_Data9<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                         Arg6,Arg7,Arg8,Arg9> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for member functions as well,
-                                     * rather than for global functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking ten arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7, typename Arg8,
-                                    typename Arg9, typename Arg10>
-    int spawn (Mem_Fun_Data10<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                         Arg6,Arg7,Arg8,Arg9,Arg10> *mem_fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking one arguments
-                                     */
-    template <typename Arg1>
-    int spawn (Fun_Data1<Arg1> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking two arguments
-                                     */
-    template <typename Arg1, typename Arg2>
-    int spawn (Fun_Data2<Arg1,Arg2> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking three arguments
-                                     */
-    template <typename Arg1, typename Arg2, typename Arg3>
-    int spawn (Fun_Data3<Arg1,Arg2,Arg3> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking four arguments
-                                     */
-    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-    int spawn (Fun_Data4<Arg1,Arg2,Arg3,Arg4> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking five arguments
-                                     */
-    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
-      typename Arg5>
-    int spawn (Fun_Data5<Arg1,Arg2,Arg3,Arg4,Arg5> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking six arguments
-                                     */
-    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6>
-    int spawn (Fun_Data6<Arg1,Arg2,Arg3,Arg4,Arg5,
-              Arg6> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking seven arguments
-                                     */
-    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7>
-    int spawn (Fun_Data7<Arg1,Arg2,Arg3,Arg4,Arg5,
-              Arg6,Arg7> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking eigth arguments
-                                     */
-    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7, typename Arg8>
-    int spawn (Fun_Data8<Arg1,Arg2,Arg3,Arg4,Arg5,
-              Arg6,Arg7,Arg8> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking nine arguments
-                                     */
-    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7, typename Arg8,
-      typename Arg9>
-    int spawn (Fun_Data9<Arg1,Arg2,Arg3,Arg4,Arg5,
-              Arg6,Arg7,Arg8,Arg9> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * threads for funtions.
-                                     *
-                                     * This version is for member functions
-                                     * taking ten arguments
-                                     */
-    template <typename Arg1, typename Arg2, typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7, typename Arg8,
-      typename Arg9, typename Arg10>
-    int spawn (Fun_Data10<Arg1,Arg2,Arg3,Arg4,Arg5,
-              Arg6,Arg7,Arg8,Arg9,Arg10> *fun_data,
-              long flags = THR_NEW_LWP | THR_JOINABLE,
-              ACE_thread_t * = 0,
-              ACE_hthread_t *t_handle = 0,
-              long priority = ACE_DEFAULT_THREAD_PRIORITY,
-              int grp_id = -1,
-              void *stack = 0,
-              size_t stack_size = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking a single argument.
-                                     */
-    template <typename ObjectClass>
-    int spawn_n (size_t n,
-                Mem_Fun_Data0<ObjectClass> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking a single argument.
-                                     */
-    template <typename ObjectClass, typename Arg>
-    int spawn_n (size_t n,
-                Mem_Fun_Data1<ObjectClass,Arg> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking two arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2>
-    int spawn_n (size_t n,
-                Mem_Fun_Data2<ObjectClass,Arg1,Arg2> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking three arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2, typename Arg3>
-    int spawn_n (size_t n,
-                Mem_Fun_Data3<ObjectClass,Arg1,Arg2,Arg3> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking four arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-    int spawn_n (size_t n,
-                Mem_Fun_Data4<ObjectClass,Arg1,Arg2,Arg3,Arg4> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking five arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5>
-    int spawn_n (size_t n,
-                Mem_Fun_Data5<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking six arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6>
-    int spawn_n (size_t n,
-                Mem_Fun_Data6<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking seven arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7>
-    int spawn_n (size_t n,
-                Mem_Fun_Data7<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                           Arg6,Arg7> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking eight arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7, typename Arg8>
-    int spawn_n (size_t n,
-                Mem_Fun_Data8<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                          Arg6,Arg7,Arg8> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking nine arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7, typename Arg8,
-                                    typename Arg9>
-    int spawn_n (size_t n,
-                Mem_Fun_Data9<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                           Arg6,Arg7,Arg8,Arg9> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking ten arguments
-                                     */
-    template <typename ObjectClass, typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7, typename Arg8,
-                                    typename Arg9, typename Arg10>
-    int spawn_n (size_t n,
-                Mem_Fun_Data10<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                           Arg6,Arg7,Arg8,Arg9,Arg10> *mem_fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking one arguments
-                                     */
-    template < typename Arg1>
-    int spawn_n (size_t n,
-                Fun_Data1<Arg1> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking two arguments
-                                     */
-    template < typename Arg1, typename Arg2>
-    int spawn_n (size_t n,
-                Fun_Data2<Arg1,Arg2> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking three arguments
-                                     */
-    template < typename Arg1, typename Arg2,
-                                    typename Arg3>
-    int spawn_n (size_t n,
-                Fun_Data3<Arg1,Arg2,Arg3> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking four arguments
-                                     */
-    template < typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4>
-    int spawn_n (size_t n,
-                Fun_Data4<Arg1,Arg2,Arg3,Arg4> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking five arguments
-                                     */
-    template < typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5>
-    int spawn_n (size_t n,
-                Fun_Data5<Arg1,Arg2,Arg3,Arg4,Arg5> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking six arguments
-                                     */
-    template < typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6>
-    int spawn_n (size_t n,
-                Fun_Data6<Arg1,Arg2,Arg3,Arg4,Arg5,
-                Arg6> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking seven arguments
-                                     */
-    template < typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7>
-    int spawn_n (size_t n,
-                Fun_Data7<Arg1,Arg2,Arg3,Arg4,Arg5,
-                Arg6,Arg7> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking eight arguments
-                                     */
-    template < typename Arg1, typename Arg2,
-      typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7, typename Arg8>
-    int spawn_n (size_t n,
-                Fun_Data8<Arg1,Arg2,Arg3,Arg4,Arg5,
-                Arg6,Arg7,Arg8> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking nine arguments
-                                     */
-    template < typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7, typename Arg8,
-                                    typename Arg9>
-    int spawn_n (size_t n,
-                Fun_Data9<Arg1,Arg2,Arg3,Arg4,Arg5,
-                Arg6,Arg7,Arg8,Arg9> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-    
-                                    /**
-                                     * Wrapper function to allow spawning
-                                     * multiple threads for member functions
-                                     * as well, rather than for global
-                                     * functions only.
-                                     *
-                                     * This version is for member functions
-                                     * taking ten arguments
-                                     */
-    template < typename Arg1, typename Arg2,
-                                    typename Arg3, typename Arg4,
-                                    typename Arg5, typename Arg6,
-                                    typename Arg7, typename Arg8,
-                                    typename Arg9, typename Arg10>
-    int spawn_n (size_t n,
-                Fun_Data10<Arg1,Arg2,Arg3,Arg4,Arg5,
-                Arg6,Arg7,Arg8,Arg9,Arg10> *fun_data,
-                long flags = THR_NEW_LWP | THR_JOINABLE,
-                long priority = ACE_DEFAULT_THREAD_PRIORITY,
-                int grp_id = -1,
-                ACE_Task_Base *task = 0,
-                ACE_hthread_t thread_handles[] = 0,
-                void *stack[] = 0,
-                size_t stack_size[] = 0);
-
-
-  private:
-
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * void member function.
-                                     */
-    template <typename Class>
-    static void * thread_entry_point0 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * unary member function.
-                                     */
-    template <typename Class, typename Arg>
-    static void * thread_entry_point1 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * binary member function.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2>
-    static void * thread_entry_point2 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * ternary member function.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2, typename Arg3>
-    static void * thread_entry_point3 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with four parameters.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-    static void * thread_entry_point4 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with five parameters.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2,
-                              typename Arg3, typename Arg4,
-                              typename Arg5>
-    static void * thread_entry_point5 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with six parameters.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2,
-                              typename Arg3, typename Arg4,
-                              typename Arg5, typename Arg6>
-    static void * thread_entry_point6 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with seven parameters.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2,
-                              typename Arg3, typename Arg4,
-                              typename Arg5, typename Arg6,
-                              typename Arg7>
-    static void * thread_entry_point7 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with eight parameters.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2,
-                              typename Arg3, typename Arg4,
-                              typename Arg5, typename Arg6,
-                              typename Arg7, typename Arg8>
-    static void * thread_entry_point8 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with nine parameters.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2,
-                              typename Arg3, typename Arg4,
-                              typename Arg5, typename Arg6,
-                              typename Arg7, typename Arg8,
-                              typename Arg9>
-    static void * thread_entry_point9 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with ten parameters.
-                                     */
-    template <typename Class, typename Arg1, typename Arg2,
-                              typename Arg3, typename Arg4,
-                              typename Arg5, typename Arg6,
-                              typename Arg7, typename Arg8,
-                              typename Arg9, typename Arg10>
-    static void * thread_entry_point10 (void *_arg);
-
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with one parameters.
-                                     */
-    template <typename Arg1>
-    static void * thread_entry_point_1 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with two parameters.
-                                     */
-    template <typename Arg1, typename Arg2>
-    static void * thread_entry_point_2 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with three parameters.
-                                     */
-    template <typename Arg1, typename Arg2,
-      typename Arg3>
-    static void * thread_entry_point_3 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with four parameters.
-                                     */
-    template <typename Arg1, typename Arg2,
-      typename Arg3, typename Arg4>
-    static void * thread_entry_point_4 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with five parameters.
-                                     */
-    template <typename Arg1, typename Arg2,
-      typename Arg3, typename Arg4,
-      typename Arg5>
-    static void * thread_entry_point_5 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with six parameters.
-                                     */
-    template <typename Arg1, typename Arg2,
-      typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6>
-    static void * thread_entry_point_6 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with seven parameters.
-                                     */
-    template <typename Arg1, typename Arg2,
-      typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7>
-    static void * thread_entry_point_7 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with eight parameters.
-                                     */
-    template <typename Arg1, typename Arg2,
-      typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7, typename Arg8>
-    static void * thread_entry_point_8 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with nine parameters.
-                                     */
-    template <typename Arg1, typename Arg2,
-      typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7, typename Arg8,
-      typename Arg9>
-    static void * thread_entry_point_9 (void *_arg);
-
-                                    /**
-                                     * This is a function satisfying the
-                                     * requirements for thread entry points.
-                                     * It takes as argument all the
-                                     * information necessary to call a
-                                     * member function with ten parameters.
-                                     */
-    template <typename Arg1, typename Arg2,
-      typename Arg3, typename Arg4,
-      typename Arg5, typename Arg6,
-      typename Arg7, typename Arg8,
-      typename Arg9, typename Arg10>
-    static void * thread_entry_point_10 (void *_arg);
-
-};
-
-
-/* ------------------------------ Template functions -------------------------------- */
-
-
-template <typename ObjectClass>
-int ThreadManager::spawn (Mem_Fun_Data0<ObjectClass> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point0<ObjectClass>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg>
-int ThreadManager::spawn (Mem_Fun_Data1<ObjectClass,Arg> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point1<ObjectClass,Arg>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2>
-int ThreadManager::spawn (Mem_Fun_Data2<ObjectClass,Arg1,Arg2> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point2<ObjectClass,Arg1,Arg2>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2, typename Arg3>
-int ThreadManager::spawn (Mem_Fun_Data3<ObjectClass,Arg1,Arg2,Arg3> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point3<ObjectClass,Arg1,Arg2,Arg3>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-int ThreadManager::spawn (Mem_Fun_Data4<ObjectClass,Arg1,Arg2,Arg3,Arg4> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point4<ObjectClass,Arg1,Arg2,Arg3,Arg4>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5>
-int ThreadManager::spawn (Mem_Fun_Data5<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point5<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6>
-int ThreadManager::spawn (Mem_Fun_Data6<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point6<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7>
-int ThreadManager::spawn (Mem_Fun_Data7<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                                   Arg6,Arg7> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point7<ObjectClass,
-                                   Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8>
-int ThreadManager::spawn (Mem_Fun_Data8<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                                   Arg6,Arg7,Arg8> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point8<ObjectClass,
-                                   Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-  typename Arg3, typename Arg4,
-  typename Arg5, typename Arg6,
-  typename Arg7, typename Arg8,
-  typename Arg9>
-int ThreadManager::spawn (Mem_Fun_Data9<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                         Arg6,Arg7,Arg8,Arg9> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point9<ObjectClass,
-                                   Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8,
-                                typename Arg9, typename Arg10>
-int ThreadManager::spawn (Mem_Fun_Data10<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                                   Arg6,Arg7,Arg8,Arg9,Arg10> *mem_fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point10<ObjectClass,
-                                   Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10>,
-                                   (void*)mem_fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1>
-int ThreadManager::spawn (Fun_Data1<Arg1> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_1<
-                                   Arg1>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2>
-int ThreadManager::spawn (Fun_Data2<Arg1,Arg2> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_2
-                                   <Arg1,Arg2>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3>
-int ThreadManager::spawn (Fun_Data3<Arg1,Arg2,Arg3> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_3
-                                   <Arg1,Arg2,Arg3>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4>
-int ThreadManager::spawn (Fun_Data4<Arg1,Arg2,Arg3,Arg4> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_4<
-                                   Arg1,Arg2,Arg3,Arg4>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5>
-int ThreadManager::spawn (Fun_Data5<Arg1,Arg2,Arg3,Arg4,Arg5> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_5
-                                   <Arg1,Arg2,Arg3,Arg4,Arg5>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6>
-int ThreadManager::spawn (Fun_Data6<Arg1,Arg2,Arg3,Arg4,Arg5,
-                         Arg6> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_6
-                                   <Arg1,Arg2,Arg3,Arg4,Arg5,Arg6>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7>
-int ThreadManager::spawn (Fun_Data7<Arg1,Arg2,Arg3,Arg4,Arg5,
-                         Arg6,Arg7> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_7
-                                   <Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8>
-int ThreadManager::spawn (Fun_Data8<Arg1,Arg2,Arg3,Arg4,Arg5,
-                         Arg6,Arg7,Arg8> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_8
-                                   <Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8,
-                                typename Arg9>
-int ThreadManager::spawn (Fun_Data9<Arg1,Arg2,Arg3,Arg4,Arg5,
-                         Arg6,Arg7,Arg8,Arg9> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_9
-                                   <Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8,
-                                typename Arg9, typename Arg10>
-int ThreadManager::spawn (Fun_Data10<Arg1,Arg2,Arg3,Arg4,Arg5,
-                         Arg6,Arg7,Arg8,Arg9,Arg10> *fun_data,
-                         long flags,
-                         ACE_thread_t *t,
-                         ACE_hthread_t *t_handle,
-                         long priority,
-                         int grp_id,
-                         void *stack,
-                         size_t stack_size)
-{
-  return ACE_Thread_Manager::spawn (&ThreadManager::template thread_entry_point_10
-                                   <Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10>,
-                                   (void*)fun_data,
-                                   flags,
-                                   t,
-                                   t_handle,
-                                   priority,
-                                   grp_id,
-                                   stack,
-                                   stack_size);
-};
-
-
-template <typename ObjectClass>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data0<ObjectClass> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point0<ObjectClass>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data1<ObjectClass,Arg> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point1<ObjectClass,Arg>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data2<ObjectClass,Arg1,Arg2> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point2<ObjectClass,Arg1,Arg2>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2, typename Arg3>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data3<ObjectClass,Arg1,Arg2,Arg3> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point3<ObjectClass,Arg1,Arg2,Arg3>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data4<ObjectClass,Arg1,Arg2,Arg3,Arg4> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point4<ObjectClass,Arg1,Arg2,Arg3,Arg4>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data5<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point5<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data6<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point6<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data7<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                                      Arg6,Arg7> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point7<ObjectClass,
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data8<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                                      Arg6,Arg7,Arg8> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point8<ObjectClass,
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8,
-                                typename Arg9>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data9<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                                     Arg6,Arg7,Arg8,Arg9> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point9<ObjectClass,
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename ObjectClass, typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8,
-                                typename Arg9, typename Arg10>
-int ThreadManager::spawn_n (size_t n,
-                           Mem_Fun_Data10<ObjectClass,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                                      Arg6,Arg7,Arg8,Arg9,Arg10> *mem_fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point10<ObjectClass,
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10>,
-                                     (void*)mem_fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename Arg1>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data1<Arg1> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_1<
-                                     Arg1>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename Arg1, typename Arg2>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data2<Arg1,Arg2> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_2<
-                                     Arg1,Arg2>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data3<Arg1,Arg2,Arg3> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_3<
-                                     Arg1,Arg2,Arg3>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data4<Arg1,Arg2,Arg3,Arg4> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_4<
-                                     Arg1,Arg2,Arg3,Arg4>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data5<Arg1,Arg2,Arg3,Arg4,Arg5> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_5<
-                                     Arg1,Arg2,Arg3,Arg4,Arg5>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data6<Arg1,Arg2,Arg3,Arg4,Arg5,
-                           Arg6> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_6<
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data7<Arg1,Arg2,Arg3,Arg4,Arg5,
-                           Arg6,Arg7> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_7<
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data8<Arg1,Arg2,Arg3,Arg4,Arg5,
-                           Arg6,Arg7,Arg8> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_8<
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8,
-                                typename Arg9>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data9<Arg1,Arg2,Arg3,Arg4,Arg5,
-                           Arg6,Arg7,Arg8,Arg9> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_9<
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename Arg1, typename Arg2,
-                                typename Arg3, typename Arg4,
-                                typename Arg5, typename Arg6,
-                                typename Arg7, typename Arg8,
-                                typename Arg9, typename Arg10>
-int ThreadManager::spawn_n (size_t n,
-                           Fun_Data10<Arg1,Arg2,Arg3,Arg4,Arg5,
-                           Arg6,Arg7,Arg8,Arg9,Arg10> *fun_data,
-                           long flags,
-                           long priority,
-                           int grp_id,
-                           ACE_Task_Base *task,
-                           ACE_hthread_t thread_handles[],
-                           void *stack[],
-                           size_t stack_size[]) 
-{
-  return ACE_Thread_Manager::spawn_n (n,
-                                     &ThreadManager::template thread_entry_point_10<
-                                     Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10>,
-                                     (void*)fun_data,
-                                     flags,
-                                     priority,
-                                     grp_id,
-                                     task,
-                                     thread_handles,
-                                     stack,
-                                     stack_size);
-};
-
-
-template <typename Class>
-void * ThreadManager::thread_entry_point0 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data0<Class> *arg = reinterpret_cast<Mem_Fun_Data0<Class> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->mem_fun != 0)
-    return (arg->object->*(arg->mem_fun))();
-  else
-    {
-      (arg->object->*(arg->void_mem_fun))();
-      return 0;
-    };
-};
-
-
-template <typename Class, typename Arg>
-void * ThreadManager::thread_entry_point1 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data1<Class,Arg> *arg = reinterpret_cast<Mem_Fun_Data1<Class,Arg> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->mem_fun != 0)
-    return (arg->object->*(arg->mem_fun))(arg->arg);
-  else
-    {
-      (arg->object->*(arg->void_mem_fun))(arg->arg);
-      return 0;
-    };
-};
-
-
-template <typename Class, typename Arg1, typename Arg2>
-void * ThreadManager::thread_entry_point2 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data2<Class,Arg1,Arg2> *arg
-    = reinterpret_cast<Mem_Fun_Data2<Class,Arg1,Arg2> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->mem_fun != 0)
-    return (arg->object->*(arg->mem_fun))(arg->arg1, arg->arg2);
-  else
-    {
-      (arg->object->*(arg->void_mem_fun))(arg->arg1, arg->arg2);
-      return 0;
-    };
-};
-
-
-template <typename Class, typename Arg1, typename Arg2, typename Arg3>
-void * ThreadManager::thread_entry_point3 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data3<Class,Arg1,Arg2,Arg3> *arg
-    = reinterpret_cast<Mem_Fun_Data3<Class,Arg1,Arg2,Arg3> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->mem_fun != 0)
-    return (arg->object->*(arg->mem_fun))(arg->arg1,
-                                         arg->arg2,
-                                         arg->arg3);
-  else
-    {
-      (arg->object->*(arg->void_mem_fun))(arg->arg1,
-                                         arg->arg2,
-                                         arg->arg3);
-      return 0;
-    };
-};
-
-
-template <typename Class, typename Arg1, typename Arg2, typename Arg3, typename Arg4>
-void * ThreadManager::thread_entry_point4 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data4<Class,Arg1,Arg2,Arg3,Arg4> *arg
-    = reinterpret_cast<Mem_Fun_Data4<Class,Arg1,Arg2,Arg3,Arg4> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->mem_fun != 0)
-    return (arg->object->*(arg->mem_fun))(arg->arg1,
-                                         arg->arg2,
-                                         arg->arg3,
-                                         arg->arg4);
-  else
-    {
-      (arg->object->*(arg->void_mem_fun))(arg->arg1,
-                                         arg->arg2,
-                                         arg->arg3,
-                                         arg->arg4);
-      return 0;
-    };
-};
-
-
-template <typename Class, typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5>
-void * ThreadManager::thread_entry_point5 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data5<Class,Arg1,Arg2,Arg3,Arg4,Arg5> *arg
-    = reinterpret_cast<Mem_Fun_Data5<Class,Arg1,Arg2,Arg3,Arg4,Arg5> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->mem_fun != 0)
-    return (arg->object->*(arg->mem_fun))(arg->arg1,
-                                         arg->arg2,
-                                         arg->arg3,
-                                         arg->arg4,
-                                         arg->arg5);
-  else
-    {
-      (arg->object->*(arg->void_mem_fun))(arg->arg1,
-                                         arg->arg2,
-                                         arg->arg3,
-                                         arg->arg4,
-                                         arg->arg5);
-      return;
-    };
-};
-
-
-template <typename Class, typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6>
-void * ThreadManager::thread_entry_point6 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6> *arg
-    = reinterpret_cast<Mem_Fun_Data6<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->mem_fun != 0)
-    return (arg->object->*(arg->mem_fun))(arg->arg1,
-                                         arg->arg2,
-                                         arg->arg3,
-                                         arg->arg4,
-                                         arg->arg5,
-                                         arg->arg6);
-  else
-    {
-      (arg->object->*(arg->void_mem_fun))(arg->arg1,
-                                         arg->arg2,
-                                         arg->arg3,
-                                         arg->arg4,
-                                         arg->arg5,
-                                         arg->arg6);
-      return 0;
-    };
-};
-
-
-template <typename Class, typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6,
-                          typename Arg7>
-void * ThreadManager::thread_entry_point7 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7> *arg
-    = reinterpret_cast<Mem_Fun_Data7<Class,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                            Arg6,Arg7> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->object->*(arg->mem_fun))(arg->arg1,
-                                       arg->arg2,
-                                       arg->arg3,
-                                       arg->arg4,
-                                       arg->arg5,
-                                       arg->arg6,
-                                       arg->arg7);
-};
-
-
-template <typename Class, typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6,
-                          typename Arg7, typename Arg8>
-void * ThreadManager::thread_entry_point8 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8> *arg
-    = reinterpret_cast<Mem_Fun_Data8<Class,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                            Arg6,Arg7,Arg8> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->object->*(arg->mem_fun))(arg->arg1,
-                                       arg->arg2,
-                                       arg->arg3,
-                                       arg->arg4,
-                                       arg->arg5,
-                                       arg->arg6,
-                                       arg->arg7,
-                                       arg->arg8);
-};
-
-
-template <typename Class, typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6,
-                          typename Arg7, typename Arg8,
-                          typename Arg9>
-void * ThreadManager::thread_entry_point9 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9> *arg
-    = reinterpret_cast<Mem_Fun_Data9<Class,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                            Arg6,Arg7,Arg8,Arg9> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->object->*(arg->mem_fun))(arg->arg1,
-                                       arg->arg2,
-                                       arg->arg3,
-                                       arg->arg4,
-                                       arg->arg5,
-                                       arg->arg6,
-                                       arg->arg7,
-                                       arg->arg8,
-                                       arg->arg9);
-};
-
-
-template <typename Class, typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6,
-                          typename Arg7, typename Arg8,
-                          typename Arg9, typename Arg10>
-void * ThreadManager::thread_entry_point10 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Mem_Fun_Data10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10> *arg
-    = reinterpret_cast<Mem_Fun_Data10<Class,Arg1,Arg2,Arg3,Arg4,Arg5,
-                                            Arg6,Arg7,Arg8,Arg9,Arg10> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->object->*(arg->mem_fun))(arg->arg1,
-                                       arg->arg2,
-                                       arg->arg3,
-                                       arg->arg4,
-                                       arg->arg5,
-                                       arg->arg6,
-                                       arg->arg7,
-                                       arg->arg8,
-                                       arg->arg9,
-                                       arg->arg10);
-};
-
-
-template <typename Arg1>
-void * ThreadManager::thread_entry_point_1 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data1<Arg1> *arg
-    = reinterpret_cast<Fun_Data1<Arg1> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->fun_ptr != 0)
-    return (arg->fun_ptr)(arg->arg1);
-   else
-    {
-      (arg->void_fun_ptr)(arg->arg1);
-      return 0;
-    }; 
-};
-
-
-template <typename Arg1, typename Arg2>
-void * ThreadManager::thread_entry_point_2 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data2<Arg1,Arg2> *arg
-    = reinterpret_cast<Fun_Data2<Arg1,Arg2> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->fun_ptr != 0)
-    return (arg->fun_ptr)(arg->arg1,
-                         arg->arg2);
-  else
-    {
-      (arg->void_fun_ptr)(arg->arg1,
-                         arg->arg2);
-      return 0;
-    };
-};
-
-
-template <typename Arg1, typename Arg2,
-  typename Arg3>
-void * ThreadManager::thread_entry_point_3 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data3<Arg1,Arg2,Arg3> *arg
-    = reinterpret_cast<Fun_Data3<Arg1,Arg2,Arg3> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->fun_ptr != 0)
-    return (arg->fun_ptr)(arg->arg1,
-                         arg->arg2,
-                         arg->arg3);
-  else
-    {
-      (arg->void_fun_ptr)(arg->arg1,
-                         arg->arg2,
-                         arg->arg3);
-      return 0;
-    };
-};
-
-
-template <typename Arg1, typename Arg2,
-  typename Arg3, typename Arg4>
-void * ThreadManager::thread_entry_point_4 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data4<Arg1,Arg2,Arg3,Arg4> *arg
-    = reinterpret_cast<Fun_Data4<Arg1,Arg2,Arg3,Arg4> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->fun_ptr != 0)
-    return (arg->fun_ptr)(arg->arg1,
-                         arg->arg2,
-                         arg->arg3,
-                         arg->arg4);
-  else
-    {
-      (arg->void_fun_ptr)(arg->arg1,
-                         arg->arg2,
-                         arg->arg3,
-                         arg->arg4);
-      return 0;
-    };
-};
-
-
-template <typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5>
-void * ThreadManager::thread_entry_point_5 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data5<Arg1,Arg2,Arg3,Arg4,Arg5> *arg
-    = reinterpret_cast<Fun_Data5<Arg1,Arg2,Arg3,Arg4,Arg5> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  if (arg->fun_ptr != 0)
-    return (arg->fun_ptr)(arg->arg1,
-                         arg->arg2,
-                         arg->arg3,
-                         arg->arg4,
-                         arg->arg5);
-  else
-    {
-      (arg->void_fun_ptr)(arg->arg1,
-                         arg->arg2,
-                         arg->arg3,
-                         arg->arg4,
-                         arg->arg5);
-      return 0;
-    };
-};
-
-
-template <typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6>
-void * ThreadManager::thread_entry_point_6 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data6<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6> *arg
-    = reinterpret_cast<Fun_Data6<Arg1,Arg2,Arg3,Arg4,Arg5,
-    Arg6> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->fun_ptr)(arg->arg1,
-                       arg->arg2,
-                       arg->arg3,
-                       arg->arg4,
-                       arg->arg5,
-                       arg->arg6);
-};
-
-
-template <typename Arg1, typename Arg2,
-  typename Arg3, typename Arg4,
-  typename Arg5, typename Arg6,
-  typename Arg7>
-void * ThreadManager::thread_entry_point_7 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data7<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7> *arg
-    = reinterpret_cast<Fun_Data7<Arg1,Arg2,Arg3,Arg4,Arg5,
-    Arg6,Arg7> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->fun_ptr)(arg->arg1,
-                        arg->arg2,
-                        arg->arg3,
-                        arg->arg4,
-                        arg->arg5,
-                        arg->arg6,
-                       arg->arg7);
-};
-
-
-template <typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6,
-                          typename Arg7, typename Arg8>
-void * ThreadManager::thread_entry_point_8 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data8<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8> *arg
-    = reinterpret_cast<Fun_Data8<Arg1,Arg2,Arg3,Arg4,Arg5,
-    Arg6,Arg7,Arg8> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->fun_ptr)(arg->arg1,
-                        arg->arg2,
-                        arg->arg3,
-                        arg->arg4,
-                        arg->arg5,
-                        arg->arg6,
-                        arg->arg7,
-                        arg->arg8);
-};
-
-
-template <typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6,
-                          typename Arg7, typename Arg8,
-                          typename Arg9>
-void * ThreadManager::thread_entry_point_9 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data9<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9> *arg
-    = reinterpret_cast<Fun_Data9<Arg1,Arg2,Arg3,Arg4,Arg5,
-    Arg6,Arg7,Arg8,Arg9> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->fun_ptr)(arg->arg1,
-                        arg->arg2,
-                        arg->arg3,
-                        arg->arg4,
-                        arg->arg5,
-                        arg->arg6,
-                        arg->arg7,
-                        arg->arg8,
-                        arg->arg9);
-};
-
-template <typename Arg1, typename Arg2,
-                          typename Arg3, typename Arg4,
-                          typename Arg5, typename Arg6,
-                          typename Arg7, typename Arg8,
-                          typename Arg9, typename Arg10>
-void * ThreadManager::thread_entry_point_10 (void *_arg)
-{
-                                  // reinterpret the given pointer as
-                                  // a pointer to the structure
-                                  // containing all the necessary
-                                  // information
-  Fun_Data10<Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10> *arg
-    = reinterpret_cast<Fun_Data10<Arg1,Arg2,Arg3,Arg4,Arg5,
-    Arg6,Arg7,Arg8,Arg9,Arg10> *>(_arg);
-
-                                  // extract function pointer, object
-                                  // and argument and dispatch the
-                                  // call
-  return (arg->fun_ptr)(arg->arg1,
-                        arg->arg2,
-                        arg->arg3,
-                        arg->arg4,
-                        arg->arg5,
-                        arg->arg6,
-                        arg->arg7,
-                        arg->arg8,
-                        arg->arg9,
-                        arg->arg10);
-};
-
-
-#endif
-
-
-#endif
diff --git a/deal.II/base/source/thread_management.cc b/deal.II/base/source/thread_management.cc
new file mode 100644 (file)
index 0000000..e94b1ea
--- /dev/null
@@ -0,0 +1,206 @@
+//----------------------------  thread_management.cc  ---------------------------
+//    $Id$
+//    Version: $Name$
+//
+//    Copyright (C) 2000 by the deal.II authors
+//
+//    This file is subject to QPL and may not be  distributed
+//    without copyright and license information. Please refer
+//    to the file deal.II/doc/license.html for the  text  and
+//    further information on this license.
+//
+//----------------------------  thread_management.cc  ---------------------------
+
+
+#include <base/thread_management.h>
+
+
+#ifdef DEAL_II_USE_MT
+
+
+namespace Threads 
+{
+  FunDataCounter::FunDataCounter () :
+                 n_fun_encapsulation_objects (0),
+                 n_fun_data_base_objects (0)
+  {};
+  
+
+  
+  FunDataCounter::~FunDataCounter () 
+  {   
+    AssertThrow (n_fun_encapsulation_objects == 0,
+                ExcObjectsExist("FunEncapsulation", n_fun_encapsulation_objects));
+    AssertThrow (n_fun_data_base_objects == 0,
+                ExcObjectsExist("FunDataBase", n_fun_data_base_objects));
+  };
+      
+
+
+/**
+ * This is the global object which we will use to count the number of
+ * threads generated, and which is used to complain when there is a
+ * memory leak.
+ */
+  FunDataCounter fun_data_counter;
+
+
+  FunEncapsulation::FunEncapsulation () :
+                 fun_data_base (0)
+  {
+                                    // keep some statistics on the
+                                    // number of variables around
+    ++fun_data_counter.n_fun_encapsulation_objects;
+  };
+
+
+
+  FunEncapsulation::FunEncapsulation (FunDataBase *fun_data_base) :
+                 fun_data_base (fun_data_base)
+  {
+                                    // keep some statistics on the
+                                    // number of variables around
+    ++fun_data_counter.n_fun_encapsulation_objects;
+  };
+
+
+
+  FunEncapsulation::FunEncapsulation (const FunEncapsulation &fun_data) :
+                 fun_data_base (fun_data.fun_data_base->clone ())
+  {
+                                    // keep some statistics on the
+                                    // number of variables around
+    ++fun_data_counter.n_fun_encapsulation_objects;
+  };
+
+
+  FunEncapsulation::~FunEncapsulation ()
+  {
+                                    // wait until the data in
+                                    // fun_data_base has been copied
+                                    // and is no more needed
+    fun_data_base->lock.acquire();
+                                    // now that we have got the lock,
+                                    // we can delete the data
+    delete fun_data_base;
+    fun_data_base = 0;
+
+                                  // keep some statistics on the
+                                  // number of variables around
+    --fun_data_counter.n_fun_encapsulation_objects;
+  };
+    
+
+  const FunEncapsulation &
+  FunEncapsulation::operator = (const FunEncapsulation &/*fun_data*/)
+  {
+                                    // this is not implemented at present
+    abort ();
+  };
+
+
+
+  FunDataBase::FunDataBase (const ThreadEntryPoint thread_entry_point) :
+                 thread_entry_point (thread_entry_point)
+  {
+                                    // keep some statistics on the
+                                    // number of variables around
+    ++fun_data_counter.n_fun_data_base_objects;
+  };
+
+
+
+  FunDataBase::FunDataBase (const FunDataBase &fun_data_base) :
+                 thread_entry_point (fun_data_base.thread_entry_point)
+  {
+                                    // keep some statistics on the
+                                    // number of variables around
+    ++fun_data_counter.n_fun_data_base_objects;
+  };
+
+
+
+  FunDataBase::~FunDataBase ()
+  {
+                                    // invalidate pointer for security
+                                    // reasons. accesses to this
+                                    // pointer after lifetime of this
+                                    // object will then fail
+    thread_entry_point = 0;
+
+                                    // keep some statistics on the
+                                    // number of variables around
+    --fun_data_counter.n_fun_data_base_objects;
+  };
+
+
+    
+  void spawn (ACE_Thread_Manager     &thread_manager,
+             const FunEncapsulation &fun_data)
+  {
+                                    // lock the #fun_data_base# object
+                                    // to avoid destruction while its
+                                    // data is still accessed. the lock
+                                    // is released by the new thread
+                                    // once it has copied all data
+    fun_data.fun_data_base->lock.acquire ();
+                                    // now start the new thread
+    thread_manager.spawn (*fun_data.fun_data_base->thread_entry_point,
+                         (void*)&fun_data,
+                         THR_SCOPE_SYSTEM | THR_DETACHED);
+  };
+
+
+  
+  void spawn_n (ACE_Thread_Manager     &thread_manager,
+               const FunEncapsulation &fun_data,
+               const unsigned int      n_threads)
+  {
+    for (unsigned int i=0; i<n_threads; ++i)
+      spawn (thread_manager, fun_data);
+  };
+  
+
+
+
+  vector<pair<unsigned int,unsigned int> >
+  split_interval (const unsigned int begin,
+                 const unsigned int end,
+                 const unsigned int n_intervals)
+  {
+    Assert (end >= begin, ExcInternalError());
+    
+    const unsigned int n_elements              = end-begin;
+    const unsigned int n_elements_per_interval = n_elements / n_intervals;
+    const unsigned int residual                = n_elements % n_intervals;
+    
+    vector<pair<unsigned int,unsigned int> > return_values (n_intervals);
+
+    return_values[0].first = begin;
+    for (unsigned int i=0; i<n_intervals; ++i)
+      {
+       if (i != n_intervals-1) 
+         {
+           return_values[i].second = (return_values[i].first
+                                      + n_elements_per_interval);
+                                            // distribute residual in
+                                            // division equally among
+                                            // the first few
+                                            // subintervals
+           if (i < residual)
+             ++return_values[i].second;
+           return_values[i+1].first = return_values[i].second;
+         }
+       else
+         return_values[i].second = end;
+      };
+    return return_values;
+  };  
+  
+  
+};   // end namespace Threads
+
+
+
+#endif // DEAL_II_USE_MT
index b1611459c4aadb80b99e661878f10543525359e4..f8f5464a0afdf8600cd7a6a9a5d80fea94d53925 100644 (file)
@@ -23,7 +23,7 @@
 #include <fe/fe_values.h>
 
 #ifdef DEAL_II_USE_MT
-#include <base/thread_manager.h>
+#include <base/thread_management.h>
 #endif
 
 #include <strstream>
@@ -338,24 +338,11 @@ void DataOut<dim>::build_patches (const unsigned int n_subdivisions,
 
 #ifdef DEAL_II_USE_MT
 
-  ThreadManager thread_manager;
-  
-  typedef ThreadManager::Mem_Fun_Data1
-    <DataOut<dim>, Data> MemFunData;
-  
-                                  // One struct of this type for every thread
-  vector<MemFunData> mem_fun_data (n_threads,
-                                  MemFunData (this,
-                                              thread_data[0],
-                                              &DataOut<dim>::build_some_patches));
-  
-                                  // get start cells for each thread
+  ACE_Thread_Manager thread_manager;  
   for (unsigned int l=0;l<n_threads;++l)
-    {
-      mem_fun_data[l].arg=thread_data[l];
-      thread_manager.spawn(&mem_fun_data[l],THR_SCOPE_SYSTEM | THR_DETACHED);
-    };
-                                  // wait for all threads to return
+    Threads::spawn (thread_manager,
+                   Threads::encapsulate (&DataOut<dim>::build_some_patches)
+                   .collect_args (this, thread_data[l]));
   thread_manager.wait();
   
                                   // just one thread
index e1aebd488a8de8479265859b92e372659ea81e1c..ba11f472ff2bae48ef7525f8b9af443fd1585384 100644 (file)
                                 // if multithreaded include
                                 // ThreadManager
 #ifdef DEAL_II_USE_MT
-#include <base/thread_manager.h>
+#  include <base/thread_management.h>
 #endif
 
+
+
 #if deal_II_dimension == 1
 
 template <>
@@ -175,7 +177,7 @@ void KellyErrorEstimator<1>::estimate (const DoFHandler<1>  &dof,
     Assert (i->second->n_components == n_components, ExcInvalidBoundaryFunction());
 
 
-const unsigned int dim=1;
+  const unsigned int dim=1;
 
                                   // reserve one slot for each cell and set
                                   // it to zero
@@ -274,7 +276,7 @@ const unsigned int dim=1;
            };
 
 
-for (unsigned int component=0; component<n_components; ++component)
+         for (unsigned int component=0; component<n_components; ++component)
            if (component_mask[component] == true)
              {
                                                 // get gradient
@@ -295,8 +297,7 @@ for (unsigned int component=0; component<n_components; ++component)
 };
 
 
-// #if deal_II_dimension !=1
-#else
+#else // #if deal_II_dimension !=1
 
 
 template <int dim>
@@ -330,7 +331,7 @@ void KellyErrorEstimator<dim>::estimate_some (Data               &data,
                                          update_gradients);
 
 
-DoFHandler<dim>::active_cell_iterator cell=data.dof.begin_active();
+  DoFHandler<dim>::active_cell_iterator cell=data.dof.begin_active();
 
                                   // calculate the start cell for this
                                   // thread. the enumeration is choosen
@@ -354,7 +355,7 @@ DoFHandler<dim>::active_cell_iterator cell=data.dof.begin_active();
            continue;
 
 
-// if the neighboring cell is less
+                                          // if the neighboring cell is less
                                           // refined than the present one, then
                                           // do nothing since we integrate
                                           // over the subfaces when we visit
@@ -465,30 +466,11 @@ void KellyErrorEstimator<dim>::estimate (const DoFHandler<dim>   &dof,
                                   // if multithreading is used
 #ifdef DEAL_II_USE_MT
 
-  ThreadManager thread_manager;
-  
-                                  // all data needed to start
-                                  // one thread is gathered
-                                  // in this struct.
-  typedef ThreadManager::Fun_Data2
-    <class Data &, unsigned int > FunData;
-  
-                                  // One struct of this type for every thread
-  vector<FunData>
-    fun_data (data.n_threads,
-             FunData (data,0,&KellyErrorEstimator::estimate_some));
-
-
-                                  // get start cells for each thread
-  for (unsigned int l=0;l<data.n_threads;++l)
-    fun_data[l].arg2=l;
-    
-    
-                                  // now spawn the threads
+  ACE_Thread_Manager thread_manager;
   for (unsigned int i=0;i<data.n_threads; ++i)
-    thread_manager.spawn(&fun_data[i],THR_SCOPE_SYSTEM | THR_DETACHED);
-    
-                                  // wait for all threads to return
+    Threads::spawn (thread_manager,
+                   Threads::encapsulate (&KellyErrorEstimator<dim>::estimate_some)
+                   .collect_args (data, i));
   thread_manager.wait();
   
                                   // ... ifdef DEAL_II_USE_MT
@@ -500,7 +482,7 @@ void KellyErrorEstimator<dim>::estimate (const DoFHandler<dim>   &dof,
 #endif
 
 
-// finally add up the contributions of the
+                                  // finally add up the contributions of the
                                   // faces for each cell
   
                                   // reserve one slot for each cell and set
@@ -612,7 +594,7 @@ integrate_over_regular_face (Data                       &data,
     };
 
 
-// now psi contains the following:
+                                  // now psi contains the following:
                                   // - for an internal face, psi=[grad u]
                                   // - for a neumann boundary face,
                                   //   psi=grad u
index 8420d91fcf42869a166eb8a9aa1b32dbd1b408bf..506447e58f43e3b03628ec6c3ade3418d5aaf954 100644 (file)
@@ -19,8 +19,7 @@
 #include <lac/vector.h>
 
 #ifdef DEAL_II_USE_MT
-#  include <base/thread_manager.h>
-#  define NTHREADS 4
+#  include <base/thread_management.h>
 #endif
 
 #include <functional>
@@ -178,6 +177,7 @@ TimeDependent::postprocess ()
 };
 
 
+
 void TimeDependent::start_sweep (const unsigned int s) 
 {
   sweep_no = s;
@@ -200,29 +200,19 @@ void TimeDependent::start_sweep (const unsigned int s)
 };
 
 
+
 void TimeDependent::end_sweep (const unsigned int n_threads)
 {
 #ifdef DEAL_II_USE_MT
-                                  // set up the data needed by each
-                                  // thread
-  typedef ThreadManager::Mem_Fun_Data2<TimeDependent,unsigned int,unsigned int> MemFunData;
-  vector<MemFunData> mem_fun_data (n_threads,
-                                  MemFunData(this, 0, 0, &TimeDependent::end_sweep));
   const unsigned int stride = timesteps.size() / n_threads;
+  ACE_Thread_Manager thread_manager;
   for (unsigned int i=0; i<n_threads; ++i)
-    {
-      mem_fun_data[i].arg1 = i*stride;
-      mem_fun_data[i].arg2 = (i+1)*stride;
-    };
-  mem_fun_data.back().arg2 = timesteps.size();
-
-                                  // spawn the threads...
-  ThreadManager thread_manager;
-  for (unsigned int i=0; i<n_threads; ++i)
-    thread_manager.spawn (&mem_fun_data[i],
-                         THR_SCOPE_SYSTEM | THR_DETACHED);
-
-                                  // ...and wait for their return
+    Threads::spawn (thread_manager,
+                   Threads::encapsulate (&TimeDependent::end_sweep)
+                   .collect_args (this, i*stride,
+                                  (i == n_threads-1 ?
+                                   timesteps.size() :
+                                   (i+1)*stride)));
   thread_manager.wait();
   
 #else
@@ -557,7 +547,7 @@ adapt_grids (const Triangulation<dim>::cell_iterator &cell1,
     };
 
 
-if (!cell1->has_children() && !cell2->has_children())
+  if (!cell1->has_children() && !cell2->has_children())
                                     // none of the two have children, so
                                     // make sure that not one is flagged
                                     // for refinement and the other for
@@ -579,7 +569,7 @@ if (!cell1->has_children() && !cell2->has_children())
     };
 
 
-if (cell1->has_children() && !cell2->has_children())
+  if (cell1->has_children() && !cell2->has_children())
                                     // cell1 has children, cell2 has not
                                     // -> cell2 needs to be refined if any
                                     // of cell1's children is flagged
@@ -690,7 +680,7 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
                                p_coarsening_threshold=0;
 
 
-// if we are to do some cell number
+                                  // if we are to do some cell number
                                   // correction steps, we have to find out
                                   // which further cells (beyond
                                   // refinement_threshold) to refine in case
@@ -720,7 +710,7 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
     };
 
 
-// actually flag cells the first time
+                                  // actually flag cells the first time
   tria->refine (criteria, refinement_threshold);
   tria->coarsen (criteria, coarsening_threshold);
 
@@ -788,7 +778,7 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
        previous_tria->prepare_coarsening_and_refinement ();
 
 
-// now count the number of elements
+                                        // now count the number of elements
                                             // which will result on the previous
                                             // grid after it will be refined. The
                                             // number which will really result
@@ -1005,7 +995,7 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
          };
 
 
-// flag cells finally
+                                        // flag cells finally
        tria->refine (criteria, refinement_threshold);
        tria->coarsen (criteria, coarsening_threshold);
       };
@@ -1023,7 +1013,7 @@ void TimeStepBase_Tria<dim>::refine_grid (const RefinementData refinement_data)
        = dynamic_cast<const TimeStepBase_Tria<dim>*>(previous_timestep)->tria;
 
 
-// if we used the dual estimator, we
+                                      // if we used the dual estimator, we
                                       // computed the error information on
                                       // a time slab, rather than on a level
                                       // of its own. we then mirror the
diff --git a/deal.II/doc/news/2000/02.html b/deal.II/doc/news/2000/02.html
new file mode 100644 (file)
index 0000000..1633d11
--- /dev/null
@@ -0,0 +1,29 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN"
+   "http://www.w3.org/TR/REC-html40/strict.dtd">
+<html>
+  <head>
+    <link href="../../screen.css" rel="StyleSheet" title="deal.II Homepage" media="screen">
+    <link href="../../print.css" rel="StyleSheet" title="deal.II Homepage" media="print">
+    <title>The deal.II news page</title>
+    <meta name="author" content="Wolfgang Bangerth">
+    <meta name="keywords" content="deal.II"></head>
+
+<body>
+
+
+
+<h2>New multithreading scheme</h2>
+
+<p>
+After the old scheme to implement multithreading in
+<acronym>deal.II</acronym> has proven to be too difficult, we
+implemented something that is significantly more complex, but at the
+same time significantly simpler to use. There is also a report on this
+subject upcoming, which can be accessed from the
+<a href="../../documentation.html" target="body">documentation</a>
+page.
+</p>
+
+</body>
+</html>
+
index ae1094c8ac6ceeb48e629e60162657679dc29dbc..2ee2cb0a36aace788902bb7f8a393052774a372e 100644 (file)
 </ol>
 
 <h3>base</h3>
-<ol>
 
-  <li> Improved: <code class="class">Subscriptor</code> prints the real class name
-  if a subscribed object is deleted.
+<ol>
+  <li> New multithreading scheme is implemented.
 
+  <li> Improved: <code class="class">Subscriptor</code> prints the
+       real class name if a subscribed object is deleted.
 </ol>
+
+
 <h3>lac</h3>
 
 <ol>
index 09922cf98195e5fb5b8ab2e8587273310f6c2a31..5ab128b197f53d511982fe3893389fc1afcbe7e8 100644 (file)
     </p>
 
     <dl>
+      <dt>
+          <strong>2000/04/14: The new multithreading scheme is now in
+          place</strong> 
+      </dt>
+      <dd>
+      (<a href="2000/02.html" target="body">full text</a>)
+      </dd>
+
+
       <dt>
           <strong>Changes after version 3.0</strong>
       </dt>
index ce27fd0a1e60f2411373491751b5cce9097c7e95..6eee33caa55011b08893d65c536c4f3bfe93b0d0 100644 (file)
@@ -634,18 +634,21 @@ class SparseMatrix : public Subscriptor
                               somenumber               *partial_sum) const;
 
                                     /**
-                                     * Version of #residual# which only
-                                     * performs its actions on the region
-                                     * defined by #[begin_row,end_row)#. This
-                                     * function is called by #residual# in
-                                     * the case of enabled multithreading.
+                                     * Version of #residual# which
+                                     * only performs its actions on
+                                     * the region defined by
+                                     * #[begin_row,end_row)# (these
+                                     * numbers are the components of
+                                     * #interval#). This function is
+                                     * called by #residual# in the
+                                     * case of enabled
+                                     * multithreading.
                                      */
     template <typename somenumber>
     void threaded_residual (Vector<somenumber>       &dst,
                            const Vector<somenumber> &u,
                            const Vector<somenumber> &b,
-                           const unsigned int        begin_row,
-                           const unsigned int        end_row,
+                           const pair<unsigned int,unsigned int> &interval,
                            somenumber               *partial_norm) const;
 
 
index cc03f21d1c3e0e34d563a754212a6cee06c21f69..5492ec15f00054339110f196f5aaa6bda7d203a2 100644 (file)
@@ -26,7 +26,7 @@
 #  include <vector>
 #  include <numeric>
 
-#  include <base/thread_manager.h>
+#  include <base/thread_management.h>
 #  include <base/multithread_info.h>
 #endif
 
@@ -207,34 +207,14 @@ SparseMatrix<number>::vmult (Vector<somenumber>& dst, const Vector<somenumber>&
     {
       const unsigned int n_threads = multithread_info.n_default_threads;
 
-      ThreadManager thread_manager;
-      
-      const ThreadManager::Mem_Fun_Data4<const SparseMatrix<number>,
-                                        Vector<somenumber> &,
-                                        const Vector<somenumber> &,
-                                        unsigned int,
-                                        unsigned int> 
-       mem_fun_data_all (this, dst, src, 0, 0,
-                         &SparseMatrix<number>::template threaded_vmult<somenumber>  );
-      vector<ThreadManager::Mem_Fun_Data4<const SparseMatrix<number>,
-                                          Vector<somenumber> &,
-                                          const Vector<somenumber> &,
-                                          unsigned int,
-                                          unsigned int> >
-       mem_fun_data(n_threads, mem_fun_data_all);
-  
-                                      // spawn some jobs...
+      ACE_Thread_Manager thread_manager;
       for (unsigned int i=0; i<n_threads; ++i)
-       {
-                                          // compute the range of rows
-                                          // they are to serve
-         mem_fun_data[i].arg3 = n_rows * i / n_threads;
-         mem_fun_data[i].arg4 = n_rows * (i+1) / n_threads;
-         
-         thread_manager.spawn (&mem_fun_data[i], THR_SCOPE_SYSTEM | THR_DETACHED);
-       };
-      
-                                      // ... and wait until they're finished
+       Threads::spawn (thread_manager,
+                       Threads::encapsulate (&SparseMatrix<number>::
+                                             template threaded_vmult<somenumber>)
+                       .collect_args (this, dst, src,
+                                      n_rows * i / n_threads,
+                                      n_rows * (i+1) / n_threads));
       thread_manager.wait ();
 
       return;
@@ -373,38 +353,20 @@ SparseMatrix<number>::matrix_norm (const Vector<somenumber>& v) const
     {
       const unsigned int n_threads = multithread_info.n_default_threads;
 
-      ThreadManager thread_manager;
-      
-      const ThreadManager::Mem_Fun_Data4<const SparseMatrix<number>,
-                                        const Vector<somenumber> &,
-                                        unsigned int,
-                                        unsigned int,
-                                        somenumber *> 
-       mem_fun_data_all (this, v, 0, 0, 0,
-                         &SparseMatrix<number>::template threaded_matrix_norm<somenumber>  );
-      vector<ThreadManager::Mem_Fun_Data4<const SparseMatrix<number>,
-                                          const Vector<somenumber> &,
-                                          unsigned int,
-                                          unsigned int,
-                                         somenumber *> >
-       mem_fun_data(n_threads, mem_fun_data_all);
-
                                       // space for the norms of
                                       // the different parts
       vector<somenumber> partial_sums (n_threads, 0);
-      
+      ACE_Thread_Manager thread_manager;
                                       // spawn some jobs...
       for (unsigned int i=0; i<n_threads; ++i)
-       {
-                                          // compute the range of rows
-                                          // they are to serve
-         mem_fun_data[i].arg2 = n_rows * i / n_threads;
-         mem_fun_data[i].arg3 = n_rows * (i+1) / n_threads;
-         mem_fun_data[i].arg4 = &partial_sums[i];
-                 
-         thread_manager.spawn (&mem_fun_data[i],THR_SCOPE_SYSTEM | THR_DETACHED);
-       };
-      
+       Threads::spawn (thread_manager,
+                       Threads::encapsulate (&SparseMatrix<number>::
+                                             template threaded_matrix_norm<somenumber>)
+                       .collect_args (this, v,
+                                      n_rows * i / n_threads,
+                                      n_rows * (i+1) / n_threads,
+                                      &partial_sums[i]));
+
                                       // ... and wait until they're finished
       thread_manager.wait ();
                                       // accumulate the partial results
@@ -522,43 +484,21 @@ SparseMatrix<number>::residual (Vector<somenumber>       &dst,
   if (n_rows/multithread_info.n_default_threads > 2000)
     {
       const unsigned int n_threads = multithread_info.n_default_threads;
-
-      ThreadManager thread_manager;
-      
-      const ThreadManager::Mem_Fun_Data6<const SparseMatrix<number>,
-                                        Vector<somenumber> &,        // dst
-                                        const Vector<somenumber> &,  // u
-                                        const Vector<somenumber> &,  // b
-                                        unsigned int,        // begin_row
-                                        unsigned int,        // end_row
-                                        somenumber *>            // partial norm
-       mem_fun_data_all (this, dst, u, b, 0, 0, 0,
-                         &SparseMatrix<number>::template threaded_residual<somenumber>  );
-      vector<ThreadManager::Mem_Fun_Data6<const SparseMatrix<number>,
-                                          Vector<somenumber> &,
-                                          const Vector<somenumber> &,
-                                          const Vector<somenumber> &,
-                                          unsigned int,
-                                          unsigned int,
-                                         somenumber *> >
-       mem_fun_data(n_threads, mem_fun_data_all);
-
                                       // space for the square norms of
                                       // the different parts
       vector<somenumber> partial_norms (n_threads, 0);
-      
-                                      // spawn some jobs...
+      ACE_Thread_Manager thread_manager;
       for (unsigned int i=0; i<n_threads; ++i)
-       {
-                                          // compute the range of rows
-                                          // they are to serve
-         mem_fun_data[i].arg4 = n_rows * i / n_threads;
-         mem_fun_data[i].arg5 = n_rows * (i+1) / n_threads;
-         mem_fun_data[i].arg6 = &partial_norms[i];
-                 
-         thread_manager.spawn (&mem_fun_data[i],THR_SCOPE_SYSTEM | THR_DETACHED);
-       };
-      
+       Threads::spawn (thread_manager,
+                       Threads::encapsulate (&SparseMatrix<number>::
+                                             template threaded_residual<somenumber>)
+                       .collect_args (this, dst, u, b,
+                                      make_pair<unsigned int,unsigned int>
+                                      (n_rows * i / n_threads,
+                                       n_rows * (i+1) / n_threads),
+                                      &partial_norms[i]));
+
                                       // ... and wait until they're finished
       thread_manager.wait ();
                                       // accumulate the partial results
@@ -591,10 +531,12 @@ void
 SparseMatrix<number>::threaded_residual (Vector<somenumber>       &dst,
                                         const Vector<somenumber> &u,
                                         const Vector<somenumber> &b,
-                                        const unsigned int        begin_row,
-                                        const unsigned int        end_row,
+                                        const pair<unsigned int, unsigned int> &interval,
                                         somenumber               *partial_norm) const
 {
+  const unsigned int begin_row = interval.first,
+                    end_row   = interval.second;
+  
 #ifdef DEAL_II_USE_MT
   somenumber norm=0.;   
   
index 80c6337db8edf6f4b9c57113bd309f8224add2de..204e1bc99a944ee616d24ec075bb09a7759ebce5 100644 (file)
@@ -20,7 +20,7 @@
 #include <lac/vector.h>
 
 #ifdef DEAL_II_USE_MT
-#  include <base/thread_manager.h>
+#  include <base/thread_management.h>
 #endif
 
 #include <algorithm>
@@ -86,15 +86,11 @@ SparseVanka<number>::compute_inverses ()
                                   // consecutive, with other
                                   // consecutive regions where we do
                                   // not have to do something
-  typedef ThreadManager::Mem_Fun_Data2<SparseVanka<number>,unsigned int,unsigned int> MemFunData;
-  vector<MemFunData> mem_fun_data (n_threads,
-                                  MemFunData(this,
-                                             0, 0,
-                                             &SparseVanka<number>::compute_inverses));
+  vector<pair<unsigned int, unsigned int> > blocking (n_threads);
 
   unsigned int c       = 0;
   unsigned int thread  = 0;
-  mem_fun_data[0].arg1 = 0;
+  blocking[0].first = 0;
   
   for (unsigned int i=0; (i<matrix->m()) && (thread+1<n_threads); ++i)
     {
@@ -102,20 +98,25 @@ SparseVanka<number>::compute_inverses ()
        ++c;
       if (c == n_inverses_per_thread)
        {
-         mem_fun_data[thread].arg2   = i;
-         mem_fun_data[thread+1].arg1 = i;
+         blocking[thread].second  = i;
+         blocking[thread+1].first = i;
          ++thread;
 
          c = 0;
        };
     };
-  mem_fun_data[n_threads-1].arg2 = matrix->m();
+  blocking[n_threads-1].second = matrix->m();
 
+  typedef void (SparseVanka<number>::*FunPtr)(unsigned int, unsigned int);
+  FunPtr fun_ptr = &SparseVanka<number>::compute_inverses;
+  
                                   // Now spawn the threads
-  ThreadManager thread_manager;
+  ACE_Thread_Manager thread_manager;
   for (unsigned int i=0; i<n_threads; ++i)
-    thread_manager.spawn (&mem_fun_data[i], THR_SCOPE_SYSTEM | THR_DETACHED);
-
+    Threads::spawn (thread_manager,
+                   Threads::encapsulate (fun_ptr)
+                   .collect_args (this, blocking[i].first, blocking[i].second));
+  
   thread_manager.wait ();
   
 #else
@@ -558,23 +559,12 @@ void SparseBlockVanka<number>::operator() (Vector<number2>       &dst,
                                     // otherwise: blocking requested
     {
 #ifdef DEAL_II_USE_MT
-      typedef ThreadManager::Mem_Fun_Data3
-       <const SparseVanka<number>, Vector<number2>&,
-       const Vector<number2> &, const vector<bool> *> MemFunData;
-      vector<MemFunData> mem_fun_data
-       (n_blocks,
-        MemFunData (this,
-                    dst, src, 0,
-                    &SparseVanka<number>::template apply_preconditioner<number2>));
-      
-      ThreadManager thread_manager;
+      ACE_Thread_Manager thread_manager;
       for (unsigned int block=0; block<n_blocks; ++block)
-       {
-         mem_fun_data[block].arg3 = &dof_masks[block];
-
-         thread_manager.spawn (&mem_fun_data[block],
-                               THR_SCOPE_SYSTEM | THR_DETACHED);
-       };
+       Threads::spawn (thread_manager,
+                       Threads::encapsulate (&SparseVanka<number>::
+                                             template apply_preconditioner<number2>)
+                       .collect_args (this, dst, src, &dof_masks[block]));
 
       thread_manager.wait ();
 #else

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.