From: Wolfgang Bangerth Date: Thu, 13 Apr 2000 16:45:20 +0000 (+0000) Subject: Put the new multithreading scheme in place. X-Git-Tag: v8.0.0~20679 X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c972cbcd3b46135ceec4611e904fb174e4565622;p=dealii.git Put the new multithreading scheme in place. git-svn-id: https://svn.dealii.org/trunk@2714 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/base/include/base/thread_management.h b/deal.II/base/include/base/thread_management.h new file mode 100644 index 0000000000..7a1ad42aee --- /dev/null +++ b/deal.II/base/include/base/thread_management.h @@ -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 +#include +#include + +#include +#include +#include +#include + + + + +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 + 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::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 + 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::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 + 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::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 + 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::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 + 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::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 + 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::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 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::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 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::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 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::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 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::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 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::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 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::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::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 FunData1::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 FunData2::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 FunData3::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 FunData4::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 FunData5::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 + typename MemFunData0::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 + typename MemFunData1::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 + typename MemFunData2::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 + typename MemFunData3::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 + typename MemFunData4::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 + typename MemFunData5::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 + vector > + 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 > + 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 + FunData0::FunData0 (FunPtr fun_ptr) : + FunDataBase (&FunData0::thread_entry_point), + fun_ptr (fun_ptr) + {}; + + + + template + FunData0::FunData0 (const FunData0 &fun_data) : + FunDataBase (fun_data), + fun_ptr (fun_data.fun_ptr) + {}; + + + + template + FunDataBase * + FunData0::clone () const + { + return new FunData0 (*this); + }; + + + + template + void * + FunData0::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef FunData0 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + FunData0::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + FunData0::ArgCollector::collect_args () + { + return new FunData0(fun_ptr); + }; + + + +/* ---------------------- FunData1 implementation ------------------------ */ + + template + FunData1::FunData1 (FunPtr fun_ptr, + Arg1 arg1) : + FunDataBase (&FunData1::thread_entry_point), + fun_ptr (fun_ptr), + arg1 (arg1) + {}; + + + + template + FunData1::FunData1 (const FunData1 &fun_data) : + FunDataBase (fun_data), + fun_ptr (fun_data.fun_ptr), + arg1 (fun_data.arg1) + {}; + + + + template + FunDataBase * + FunData1::clone () const + { + return new FunData1 (*this); + }; + + + + template + void * + FunData1::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef FunData1 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + FunData1::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + template + FunEncapsulation + FunData1::ArgCollector::collect_args (Arg1 arg1) + { + return new FunData1(fun_ptr, arg1); + }; + + + + +/* ---------------------- FunData2 implementation ------------------------ */ + + template + FunData2::FunData2 (FunPtr fun_ptr, + Arg1 arg1, + Arg2 arg2) : + FunDataBase (&FunData2::thread_entry_point), + fun_ptr (fun_ptr), + arg1 (arg1), + arg2 (arg2) + {}; + + + + template + FunData2::FunData2 (const FunData2 &fun_data) : + FunDataBase (fun_data), + fun_ptr (fun_data.fun_ptr), + arg1 (fun_data.arg1), + arg2 (fun_data.arg2) + {}; + + + + template + FunDataBase * + FunData2::clone () const + { + return new FunData2 (*this); + }; + + + + template + void * + FunData2::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef FunData2 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + FunData2::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + FunData2::ArgCollector::collect_args (Arg1 arg1, + Arg2 arg2) + { + return new FunData2(fun_ptr, arg1, arg2); + }; + + + + +/* ---------------------- FunData3 implementation ------------------------ */ + + template + FunData3::FunData3 (FunPtr fun_ptr, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3) : + FunDataBase (&FunData3::thread_entry_point), + fun_ptr (fun_ptr), + arg1 (arg1), + arg2 (arg2), + arg3 (arg3) + {}; + + + + template + FunData3::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 + FunDataBase * + FunData3::clone () const + { + return new FunData3 (*this); + }; + + + + template + void * + FunData3::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef FunData3 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + FunData3::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + FunData3::ArgCollector::collect_args (Arg1 arg1, + Arg2 arg2, + Arg3 arg3) + { + return new FunData3(fun_ptr, arg1, arg2, arg3); + }; + + + + +/* ---------------------- FunData4 implementation ------------------------ */ + + template + FunData4::FunData4 (FunPtr fun_ptr, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4) : + FunDataBase (&FunData4::thread_entry_point), + fun_ptr (fun_ptr), + arg1 (arg1), + arg2 (arg2), + arg3 (arg3), + arg4 (arg4) + {}; + + + + template + FunData4::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 + FunDataBase * + FunData4::clone () const + { + return new FunData4 (*this); + }; + + + + template + void * + FunData4::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef FunData4 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + FunData4::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + FunData4::ArgCollector::collect_args (Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4) + { + return new FunData4(fun_ptr, arg1, arg2, arg3, arg4); + }; + + + + +/* ---------------------- FunData5 implementation ------------------------ */ + + template + FunData5::FunData5 (FunPtr fun_ptr, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4, + Arg5 arg5) : + FunDataBase (&FunData5::thread_entry_point), + fun_ptr (fun_ptr), + arg1 (arg1), + arg2 (arg2), + arg3 (arg3), + arg4 (arg4), + arg5 (arg5) + {}; + + + + template + FunData5::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 + FunDataBase * + FunData5::clone () const + { + return new FunData5 (*this); + }; + + + + template + void * + FunData5::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef FunData5 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + FunData5::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + FunData5::ArgCollector::collect_args (Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4, + Arg5 arg5) + { + return new FunData5(fun_ptr, arg1, arg2, + arg3, arg4, arg5); + }; + + + + + +/* ---------------------- MemFunData0 implementation ------------------------ */ + + template + MemFunData0::MemFunData0 (FunPtr fun_ptr, + Class *object) : + FunDataBase (&MemFunData0::thread_entry_point), + fun_ptr (fun_ptr), + object (object) + {}; + + + + template + MemFunData0::MemFunData0 (const MemFunData0 &fun_data) : + FunDataBase (fun_data), + fun_ptr (fun_data.fun_ptr), + object (fun_data.object) + {}; + + + + template + FunDataBase * + MemFunData0::clone () const + { + return new MemFunData0 (*this); + }; + + + + template + void * + MemFunData0::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef MemFunData0 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + MemFunData0::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + MemFunData0::ArgCollector::collect_args (Class *object) + { + return new MemFunData0(fun_ptr, object); + }; + + + +/* ---------------------- MemFunData1 implementation ------------------------ */ + + template + MemFunData1::MemFunData1 (FunPtr fun_ptr, + Class *object, + Arg1 arg1) : + FunDataBase (&MemFunData1::thread_entry_point), + fun_ptr (fun_ptr), + object (object), + arg1 (arg1) + {}; + + + + template + MemFunData1::MemFunData1 (const MemFunData1 &fun_data) : + FunDataBase (fun_data), + fun_ptr (fun_data.fun_ptr), + object (fun_data.object), + arg1 (fun_data.arg1) + {}; + + + + template + FunDataBase * + MemFunData1::clone () const + { + return new MemFunData1 (*this); + }; + + + + template + void * + MemFunData1::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef MemFunData1 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + MemFunData1::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + template + FunEncapsulation + MemFunData1::ArgCollector::collect_args (Class *object, + Arg1 arg1) + { + return new MemFunData1(fun_ptr, object, arg1); + }; + + + + +/* ---------------------- MemFunData2 implementation ------------------------ */ + + template + MemFunData2::MemFunData2 (FunPtr fun_ptr, + Class *object, + Arg1 arg1, + Arg2 arg2) : + FunDataBase (&MemFunData2::thread_entry_point), + fun_ptr (fun_ptr), + object (object), + arg1 (arg1), + arg2 (arg2) + {}; + + + + template + MemFunData2::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 + FunDataBase * + MemFunData2::clone () const + { + return new MemFunData2 (*this); + }; + + + + template + void * + MemFunData2::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef MemFunData2 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + MemFunData2::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + MemFunData2::ArgCollector::collect_args (Class *object, + Arg1 arg1, + Arg2 arg2) + { + return new MemFunData2(fun_ptr, object, arg1, arg2); + }; + + + + +/* ---------------------- MemFunData3 implementation ------------------------ */ + + template + MemFunData3::MemFunData3 (FunPtr fun_ptr, + Class *object, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3) : + FunDataBase (&MemFunData3::thread_entry_point), + fun_ptr (fun_ptr), + object (object), + arg1 (arg1), + arg2 (arg2), + arg3 (arg3) + {}; + + + + template + MemFunData3::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 + FunDataBase * + MemFunData3::clone () const + { + return new MemFunData3 (*this); + }; + + + + template + void * + MemFunData3::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef MemFunData3 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + MemFunData3::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + MemFunData3::ArgCollector::collect_args (Class *object, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3) + { + return new MemFunData3(fun_ptr, object, + arg1, arg2, arg3); + }; + + + + +/* ---------------------- MemFunData4 implementation ------------------------ */ + + template + MemFunData4::MemFunData4 (FunPtr fun_ptr, + Class *object, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4) : + FunDataBase (&MemFunData4::thread_entry_point), + fun_ptr (fun_ptr), + object (object), + arg1 (arg1), + arg2 (arg2), + arg3 (arg3), + arg4 (arg4) + {}; + + + + template + MemFunData4::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 + FunDataBase * + MemFunData4::clone () const + { + return new MemFunData4 (*this); + }; + + + + template + void * + MemFunData4::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef MemFunData4 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + MemFunData4::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + MemFunData4::ArgCollector::collect_args (Class *object, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4) + { + return new MemFunData4(fun_ptr, object, + arg1, arg2, arg3, arg4); + }; + + + + +/* ---------------------- MemFunData5 implementation ------------------------ */ + + template + MemFunData5::MemFunData5 (FunPtr fun_ptr, + Class *object, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4, + Arg5 arg5) : + FunDataBase (&MemFunData5::thread_entry_point), + fun_ptr (fun_ptr), + object (object), + arg1 (arg1), + arg2 (arg2), + arg3 (arg3), + arg4 (arg4), + arg5 (arg5) + {}; + + + + template + MemFunData5::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 + FunDataBase * + MemFunData5::clone () const + { + return new MemFunData5 (*this); + }; + + + + template + void * + MemFunData5::thread_entry_point (void *arg) + { + // convenience typedef, since we + // will need that class name + // several times below + typedef MemFunData5 ThisClass; + + FunEncapsulation *fun_encapsulation + = reinterpret_cast(arg); + const ThisClass *fun_data + = dynamic_cast (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 + MemFunData5::ArgCollector::ArgCollector (FunPtr fun_ptr) : + fun_ptr (fun_ptr) + {}; + + + + template + FunEncapsulation + MemFunData5::ArgCollector::collect_args (Class *object, + Arg1 arg1, + Arg2 arg2, + Arg3 arg3, + Arg4 arg4, + Arg5 arg5) + { + return new MemFunData5(fun_ptr, object, + arg1, arg2, arg3, arg4, arg5); + }; + + + + +/* ---------------------------------------------------------------- */ + + inline + FunData0::ArgCollector + encapsulate (void (*fun_ptr)()) + { + return fun_ptr; + }; + + + + template + FunData1::ArgCollector + encapsulate (void (*fun_ptr)(Arg1)) + { + return fun_ptr; + }; + + + + template + FunData2::ArgCollector + encapsulate (void (*fun_ptr)(Arg1, Arg2)) + { + return fun_ptr; + }; + + + + template + FunData3::ArgCollector + encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3)) + { + return fun_ptr; + }; + + + + template + FunData4::ArgCollector + encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4)) + { + return fun_ptr; + }; + + + template + FunData5::ArgCollector + encapsulate (void (*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5)) + { + return fun_ptr; + }; + + + template + MemFunData0::ArgCollector + encapsulate (void (Class::*fun_ptr)()) + { + return fun_ptr; + }; + + + + template + MemFunData1::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1)) + { + return fun_ptr; + }; + + + + template + MemFunData2::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2)) + { + return fun_ptr; + }; + + + + template + MemFunData3::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3)) + { + return fun_ptr; + }; + + + + template + MemFunData4::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4)) + { + return fun_ptr; + }; + + + + template + MemFunData5::ArgCollector + encapsulate (void (Class::*fun_ptr)(Arg1, Arg2, Arg3, Arg4, Arg5)) + { + return fun_ptr; + }; + + + + template + vector > + 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 > + return_values (n_intervals); + + return_values[0].first = begin; + for (unsigned int i=0; i=0' + // is checked (dist has a + // template type, which + // here is unsigned if no + // cast is performed) + advance (return_values[i].second, + static_cast(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 index db2523c1bd..0000000000 --- a/deal.II/base/include/base/thread_manager.h +++ /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 - - -/** - * 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*)¶ms, ...); - * }; - * - * 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#, 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*)¶ms, ...); - * - * ... // 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, - * 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 - * 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - int spawn (Mem_Fun_Data0 *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 - int spawn (Mem_Fun_Data1 *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 - int spawn (Mem_Fun_Data2 *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 - int spawn (Mem_Fun_Data3 *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 - int spawn (Mem_Fun_Data4 *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 - int spawn (Mem_Fun_Data5 *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 - int spawn (Mem_Fun_Data6 *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 - int spawn (Mem_Fun_Data7 *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 - int spawn (Mem_Fun_Data8 *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 - int spawn (Mem_Fun_Data9 *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 - int spawn (Mem_Fun_Data10 *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 - int spawn (Fun_Data1 *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 - int spawn (Fun_Data2 *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 - int spawn (Fun_Data3 *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 - int spawn (Fun_Data4 *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 - int spawn (Fun_Data5 *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 - int spawn (Fun_Data6 *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 - int spawn (Fun_Data7 *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 - int spawn (Fun_Data8 *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 - int spawn (Fun_Data9 *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 - int spawn (Fun_Data10 *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 - int spawn_n (size_t n, - Mem_Fun_Data0 *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 - int spawn_n (size_t n, - Mem_Fun_Data1 *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 - int spawn_n (size_t n, - Mem_Fun_Data2 *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 - int spawn_n (size_t n, - Mem_Fun_Data3 *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 - int spawn_n (size_t n, - Mem_Fun_Data4 *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 - int spawn_n (size_t n, - Mem_Fun_Data5 *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 - int spawn_n (size_t n, - Mem_Fun_Data6 *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 - int spawn_n (size_t n, - Mem_Fun_Data7 *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 - int spawn_n (size_t n, - Mem_Fun_Data8 *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 - int spawn_n (size_t n, - Mem_Fun_Data9 *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 - int spawn_n (size_t n, - Mem_Fun_Data10 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 *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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - 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 - static void * thread_entry_point_10 (void *_arg); - -}; - - -/* ------------------------------ Template functions -------------------------------- */ - - -template -int ThreadManager::spawn (Mem_Fun_Data0 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data1 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data2 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data3 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data4 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data5 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data6 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data7 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data8 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data9 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Mem_Fun_Data10 *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, - (void*)mem_fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Fun_Data1 *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 -int ThreadManager::spawn (Fun_Data2 *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 - , - (void*)fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Fun_Data3 *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 - , - (void*)fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Fun_Data4 *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 -int ThreadManager::spawn (Fun_Data5 *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 - , - (void*)fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Fun_Data6 *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 - , - (void*)fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Fun_Data7 *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 - , - (void*)fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Fun_Data8 *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 - , - (void*)fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Fun_Data9 *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 - , - (void*)fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn (Fun_Data10 *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 - , - (void*)fun_data, - flags, - t, - t_handle, - priority, - grp_id, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data0 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data1 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data2 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data3 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data4 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data5 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data6 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data7 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data8 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data9 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Mem_Fun_Data10 *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, - (void*)mem_fun_data, - flags, - priority, - grp_id, - task, - thread_handles, - stack, - stack_size); -}; - - -template -int ThreadManager::spawn_n (size_t n, - Fun_Data1 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data2 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data3 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data4 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data5 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data6 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data7 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data8 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data9 *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 -int ThreadManager::spawn_n (size_t n, - Fun_Data10 *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 -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 *arg = reinterpret_cast *>(_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 -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 *arg = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 -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 *arg - = reinterpret_cast *>(_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 index 0000000000..e94b1eac67 --- /dev/null +++ b/deal.II/base/source/thread_management.cc @@ -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 + + +#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 > + 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 > return_values (n_intervals); + + return_values[0].first = begin; + for (unsigned int i=0; i #ifdef DEAL_II_USE_MT -#include +#include #endif #include @@ -338,24 +338,11 @@ void DataOut::build_patches (const unsigned int n_subdivisions, #ifdef DEAL_II_USE_MT - ThreadManager thread_manager; - - typedef ThreadManager::Mem_Fun_Data1 - , Data> MemFunData; - - // One struct of this type for every thread - vector mem_fun_data (n_threads, - MemFunData (this, - thread_data[0], - &DataOut::build_some_patches)); - - // get start cells for each thread + ACE_Thread_Manager thread_manager; for (unsigned int l=0;l::build_some_patches) + .collect_args (this, thread_data[l])); thread_manager.wait(); // just one thread diff --git a/deal.II/deal.II/source/numerics/error_estimator.cc b/deal.II/deal.II/source/numerics/error_estimator.cc index e1aebd488a..ba11f472ff 100644 --- a/deal.II/deal.II/source/numerics/error_estimator.cc +++ b/deal.II/deal.II/source/numerics/error_estimator.cc @@ -33,9 +33,11 @@ // if multithreaded include // ThreadManager #ifdef DEAL_II_USE_MT -#include +# include #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 @@ -330,7 +331,7 @@ void KellyErrorEstimator::estimate_some (Data &data, update_gradients); -DoFHandler::active_cell_iterator cell=data.dof.begin_active(); + DoFHandler::active_cell_iterator cell=data.dof.begin_active(); // calculate the start cell for this // thread. the enumeration is choosen @@ -354,7 +355,7 @@ DoFHandler::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::estimate (const DoFHandler &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 - FunData; - - // One struct of this type for every thread - vector - fun_data (data.n_threads, - FunData (data,0,&KellyErrorEstimator::estimate_some)); - - - // get start cells for each thread - for (unsigned int l=0;l::estimate_some) + .collect_args (data, i)); thread_manager.wait(); // ... ifdef DEAL_II_USE_MT @@ -500,7 +482,7 @@ void KellyErrorEstimator::estimate (const DoFHandler &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 diff --git a/deal.II/deal.II/source/numerics/time_dependent.cc b/deal.II/deal.II/source/numerics/time_dependent.cc index 8420d91fcf..506447e58f 100644 --- a/deal.II/deal.II/source/numerics/time_dependent.cc +++ b/deal.II/deal.II/source/numerics/time_dependent.cc @@ -19,8 +19,7 @@ #include #ifdef DEAL_II_USE_MT -# include -# define NTHREADS 4 +# include #endif #include @@ -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 MemFunData; - vector 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::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::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::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::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::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::refine_grid (const RefinementData refinement_data) = dynamic_cast*>(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 index 0000000000..1633d11c24 --- /dev/null +++ b/deal.II/doc/news/2000/02.html @@ -0,0 +1,29 @@ + + + + + + The deal.II news page + + + + + + + +

New multithreading scheme

+ +

+After the old scheme to implement multithreading in +deal.II 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 +documentation +page. +

+ + + + diff --git a/deal.II/doc/news/2000/c-3-0.html b/deal.II/doc/news/2000/c-3-0.html index ae1094c8ac..2ee2cb0a36 100644 --- a/deal.II/doc/news/2000/c-3-0.html +++ b/deal.II/doc/news/2000/c-3-0.html @@ -20,12 +20,15 @@

base

-
    -
  1. Improved: Subscriptor prints the real class name - if a subscribed object is deleted. +
      +
    1. New multithreading scheme is implemented. +
    2. Improved: Subscriptor prints the + real class name if a subscribed object is deleted.
    + +

    lac

      diff --git a/deal.II/doc/news/news.html b/deal.II/doc/news/news.html index 09922cf981..5ab128b197 100644 --- a/deal.II/doc/news/news.html +++ b/deal.II/doc/news/news.html @@ -21,6 +21,15 @@

      +
      + 2000/04/14: The new multithreading scheme is now in + place +
      +
      + (full text) +
      + +
      Changes after version 3.0
      diff --git a/deal.II/lac/include/lac/sparse_matrix.h b/deal.II/lac/include/lac/sparse_matrix.h index ce27fd0a1e..6eee33caa5 100644 --- a/deal.II/lac/include/lac/sparse_matrix.h +++ b/deal.II/lac/include/lac/sparse_matrix.h @@ -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 void threaded_residual (Vector &dst, const Vector &u, const Vector &b, - const unsigned int begin_row, - const unsigned int end_row, + const pair &interval, somenumber *partial_norm) const; diff --git a/deal.II/lac/include/lac/sparse_matrix.templates.h b/deal.II/lac/include/lac/sparse_matrix.templates.h index cc03f21d1c..5492ec15f0 100644 --- a/deal.II/lac/include/lac/sparse_matrix.templates.h +++ b/deal.II/lac/include/lac/sparse_matrix.templates.h @@ -26,7 +26,7 @@ # include # include -# include +# include # include #endif @@ -207,34 +207,14 @@ SparseMatrix::vmult (Vector& dst, const Vector& { const unsigned int n_threads = multithread_info.n_default_threads; - ThreadManager thread_manager; - - const ThreadManager::Mem_Fun_Data4, - Vector &, - const Vector &, - unsigned int, - unsigned int> - mem_fun_data_all (this, dst, src, 0, 0, - &SparseMatrix::template threaded_vmult ); - vector, - Vector &, - const Vector &, - 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:: + template threaded_vmult) + .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::matrix_norm (const Vector& v) const { const unsigned int n_threads = multithread_info.n_default_threads; - ThreadManager thread_manager; - - const ThreadManager::Mem_Fun_Data4, - const Vector &, - unsigned int, - unsigned int, - somenumber *> - mem_fun_data_all (this, v, 0, 0, 0, - &SparseMatrix::template threaded_matrix_norm ); - vector, - const Vector &, - unsigned int, - unsigned int, - somenumber *> > - mem_fun_data(n_threads, mem_fun_data_all); - // space for the norms of // the different parts vector partial_sums (n_threads, 0); - + ACE_Thread_Manager thread_manager; // spawn some jobs... for (unsigned int i=0; i:: + template threaded_matrix_norm) + .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::residual (Vector &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, - Vector &, // dst - const Vector &, // u - const Vector &, // b - unsigned int, // begin_row - unsigned int, // end_row - somenumber *> // partial norm - mem_fun_data_all (this, dst, u, b, 0, 0, 0, - &SparseMatrix::template threaded_residual ); - vector, - Vector &, - const Vector &, - const Vector &, - unsigned int, - unsigned int, - somenumber *> > - mem_fun_data(n_threads, mem_fun_data_all); - + // space for the square norms of // the different parts vector partial_norms (n_threads, 0); - - // spawn some jobs... + ACE_Thread_Manager thread_manager; for (unsigned int i=0; i:: + template threaded_residual) + .collect_args (this, dst, u, b, + make_pair + (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::threaded_residual (Vector &dst, const Vector &u, const Vector &b, - const unsigned int begin_row, - const unsigned int end_row, + const pair &interval, somenumber *partial_norm) const { + const unsigned int begin_row = interval.first, + end_row = interval.second; + #ifdef DEAL_II_USE_MT somenumber norm=0.; diff --git a/deal.II/lac/include/lac/sparse_vanka.templates.h b/deal.II/lac/include/lac/sparse_vanka.templates.h index 80c6337db8..204e1bc99a 100644 --- a/deal.II/lac/include/lac/sparse_vanka.templates.h +++ b/deal.II/lac/include/lac/sparse_vanka.templates.h @@ -20,7 +20,7 @@ #include #ifdef DEAL_II_USE_MT -# include +# include #endif #include @@ -86,15 +86,11 @@ SparseVanka::compute_inverses () // consecutive, with other // consecutive regions where we do // not have to do something - typedef ThreadManager::Mem_Fun_Data2,unsigned int,unsigned int> MemFunData; - vector mem_fun_data (n_threads, - MemFunData(this, - 0, 0, - &SparseVanka::compute_inverses)); + vector > 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; (im()) && (thread+1::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::*FunPtr)(unsigned int, unsigned int); + FunPtr fun_ptr = &SparseVanka::compute_inverses; + // Now spawn the threads - ThreadManager thread_manager; + ACE_Thread_Manager thread_manager; for (unsigned int i=0; i::operator() (Vector &dst, // otherwise: blocking requested { #ifdef DEAL_II_USE_MT - typedef ThreadManager::Mem_Fun_Data3 - , Vector&, - const Vector &, const vector *> MemFunData; - vector mem_fun_data - (n_blocks, - MemFunData (this, - dst, src, 0, - &SparseVanka::template apply_preconditioner)); - - ThreadManager thread_manager; + ACE_Thread_Manager thread_manager; for (unsigned int block=0; block:: + template apply_preconditioner) + .collect_args (this, dst, src, &dof_masks[block])); thread_manager.wait (); #else