From 2a6579284071e72c88f9b20afdf8fce569fd9ded Mon Sep 17 00:00:00 2001 From: wolf Date: Tue, 7 Sep 1999 12:49:11 +0000 Subject: [PATCH] Add a class extending the ACE_Thread_Manager class for calls to member functions. git-svn-id: https://svn.dealii.org/trunk@1725 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/base/include/base/thread_manager.h | 939 +++++++++++++++++++++ 1 file changed, 939 insertions(+) create mode 100644 deal.II/base/include/base/thread_manager.h diff --git a/deal.II/base/include/base/thread_manager.h b/deal.II/base/include/base/thread_manager.h new file mode 100644 index 0000000000..bc965ea2cc --- /dev/null +++ b/deal.II/base/include/base/thread_manager.h @@ -0,0 +1,939 @@ +/*---------------------------- thread_manager.h ---------------------------*/ +/* $Id$ */ +#ifndef __thread_manager_H +#define __thread_manager_H +/*---------------------------- 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. + * + * @author Wolfgang Bangerth, 1999 + */ +class ThreadManager : public ACE_Thread_Manager +{ + public: + /** + * 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. + */ + template + struct Mem_Fun_Data1 + { + /** + * Convenience #typedef# for the + * member functions data type. + */ + typedef void * (Class::*MemFun) (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. + */ + MemFun mem_fun; + + Mem_Fun_Data1 (Class *object, + Arg arg, + MemFun mem_fun) : + object (object), + arg (arg), + mem_fun (mem_fun) {}; + }; + + template + struct Mem_Fun_Data2 + { + typedef void * (Class::*MemFun) (Arg1, Arg2); + Class *object; + Arg1 arg1; + Arg2 arg2; + MemFun mem_fun; + + Mem_Fun_Data2 (Class *object, + Arg1 arg1, + Arg2 arg2, + MemFun mem_fun) : + object (object), + arg1 (arg1), + arg2 (arg2), + mem_fun (mem_fun) {}; + }; + + + template + struct Mem_Fun_Data3 + { + typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3); + Class *object; + Arg1 arg1; + Arg2 arg2; + Arg3 arg3; + MemFun 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) {}; + }; + + + template + struct Mem_Fun_Data4 + { + typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4); + Class *object; + Arg1 arg1; + Arg2 arg2; + Arg3 arg3; + Arg4 arg4; + MemFun 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) {}; + }; + + template + struct Mem_Fun_Data5 + { + typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4, Arg5); + Class *object; + Arg1 arg1; + Arg2 arg2; + Arg3 arg3; + Arg4 arg4; + Arg5 arg5; + MemFun 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) {}; + }; + + + template + struct Mem_Fun_Data6 + { + typedef void * (Class::*MemFun) (Arg1, Arg2, Arg3, Arg4, Arg5, Arg6); + Class *object; + Arg1 arg1; + Arg2 arg2; + Arg3 arg3; + Arg4 arg4; + Arg5 arg5; + Arg6 arg6; + MemFun 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) {}; + }; + + + + /** + * 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 + * 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); + + private: + + + /** + * 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); +}; + + + +/* ------------------------------ Template functions -------------------------------- */ + + +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 (&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 (&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 (&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 (&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 (&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 (&thread_entry_point6, + (void*)mem_fun_data, + flags, + t, + t_handle, + priority, + grp_id, + 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, + &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, + &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, + &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, + &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, + &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, + &thread_entry_point6, + (void*)mem_fun_data, + flags, + priority, + grp_id, + task, + thread_handles, + stack, + stack_size); +}; + + + +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 + return (arg->object->*(arg->mem_fun))(arg->arg); +}; + + + +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 + return (arg->object->*(arg->mem_fun))(arg->arg1, arg->arg2); +}; + + + +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 + return (arg->object->*(arg->mem_fun))(arg->arg1, + arg->arg2, + arg->arg3); +}; + + + +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 + return (arg->object->*(arg->mem_fun))(arg->arg1, + arg->arg2, + arg->arg3, + arg->arg4); +}; + + + +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 + return (arg->object->*(arg->mem_fun))(arg->arg1, + arg->arg2, + arg->arg3, + arg->arg4, + arg->arg5); +}; + + + +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 + return (arg->object->*(arg->mem_fun))(arg->arg1, + arg->arg2, + arg->arg3, + arg->arg4, + arg->arg5, + arg->arg6); +}; + + +#endif + +/*---------------------------- thread_manager.h ---------------------------*/ +/* end of #ifndef __thread_manager_H */ +#endif +/*---------------------------- thread_manager.h ---------------------------*/ -- 2.39.5